diff --git a/samples/ControlGallery/Views/Grids.razor b/samples/ControlGallery/Views/Grids.razor
new file mode 100644
index 00000000..5212df1e
--- /dev/null
+++ b/samples/ControlGallery/Views/Grids.razor
@@ -0,0 +1,63 @@
+@page "/grids"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/ControlGallery/Views/PlaygroundList.razor b/samples/ControlGallery/Views/PlaygroundList.razor
index 144ebc12..d52761a2 100644
--- a/samples/ControlGallery/Views/PlaygroundList.razor
+++ b/samples/ControlGallery/Views/PlaygroundList.razor
@@ -4,14 +4,15 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/samples/ControlGallery/Views/ShellPropertiesPlayground.razor b/samples/ControlGallery/Views/ShellPropertiesPlayground.razor
index 008153ff..ac677df0 100644
--- a/samples/ControlGallery/Views/ShellPropertiesPlayground.razor
+++ b/samples/ControlGallery/Views/ShellPropertiesPlayground.razor
@@ -1,4 +1,9 @@
-
+
+
@@ -11,10 +16,6 @@
-
-
diff --git a/src/Microsoft.MobileBlazorBindings/AttachedPropertyRegistry.cs b/src/Microsoft.MobileBlazorBindings/AttachedPropertyRegistry.cs
new file mode 100644
index 00000000..f0ea5c73
--- /dev/null
+++ b/src/Microsoft.MobileBlazorBindings/AttachedPropertyRegistry.cs
@@ -0,0 +1,19 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+using Microsoft.Maui.Controls;
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.MobileBlazorBindings
+{
+ public static class AttachedPropertyRegistry
+ {
+ internal static readonly Dictionary> AttachedPropertyHandlers = new();
+
+ public static void RegisterAttachedPropertyHandler(string propertyName, Action handler)
+ {
+ AttachedPropertyHandlers[propertyName] = handler;
+ }
+ }
+}
diff --git a/src/Microsoft.MobileBlazorBindings/Elements/AttributeHelper.Common.cs b/src/Microsoft.MobileBlazorBindings/Elements/AttributeHelper.Common.cs
index f64e8d2a..9b2e6f16 100644
--- a/src/Microsoft.MobileBlazorBindings/Elements/AttributeHelper.Common.cs
+++ b/src/Microsoft.MobileBlazorBindings/Elements/AttributeHelper.Common.cs
@@ -12,16 +12,26 @@ public static partial class AttributeHelper
{
public static bool GetBool(object value, bool defaultValueIfNull = default)
{
- return (value == null)
- ? defaultValueIfNull
- : (string.Equals((string)value, "1", StringComparison.Ordinal));
+ return value switch
+ {
+ null => defaultValueIfNull,
+ bool bln => bln,
+ string str when str == "1" => true,
+ string str when str == "0" => false,
+ string str when bool.TryParse(str, out var bln) => bln,
+ _ => throw new NotSupportedException($"Cannot get bool value from {value.GetType().Name} attribute.")
+ };
}
public static int GetInt(object value, int defaultValueIfNull = default)
{
- return (value == null)
- ? defaultValueIfNull
- : int.Parse((string)value, CultureInfo.InvariantCulture);
+ return value switch
+ {
+ null => defaultValueIfNull,
+ int i => i,
+ string str => int.Parse(str, CultureInfo.InvariantCulture),
+ _ => throw new NotSupportedException($"Cannot get int value from {value.GetType().Name} attribute.")
+ };
}
///
diff --git a/src/Microsoft.MobileBlazorBindings/Elements/AttributeHelper.Object.cs b/src/Microsoft.MobileBlazorBindings/Elements/AttributeHelper.Object.cs
index 1598fa56..c452608d 100644
--- a/src/Microsoft.MobileBlazorBindings/Elements/AttributeHelper.Object.cs
+++ b/src/Microsoft.MobileBlazorBindings/Elements/AttributeHelper.Object.cs
@@ -1,12 +1,41 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
+using Microsoft.Maui;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui.Graphics;
using System;
namespace Microsoft.MobileBlazorBindings.Elements
{
public static partial class AttributeHelper
{
+ public static object ObjectToAttribute(object value)
+ {
+ if (value == null || value is string || value is int || value is Delegate)
+ return value;
+
+ if (value is bool boolValue)
+ return boolValue ? "1" : "0";
+
+ return value switch
+ {
+ double d => DoubleToString(d),
+ float f => SingleToString(f),
+ uint ui => UInt32ToString(ui),
+ Color color => ColorToString(color),
+ Rect rect => RectToString(rect),
+ CornerRadius cornerRadius => CornerRadiusToString(cornerRadius),
+ DateTime dateTime => DateTimeToString(dateTime),
+ GridLength gridLength => GridLengthToString(gridLength),
+ LayoutOptions layoutOptions => LayoutOptionsToString(layoutOptions),
+ Thickness thickness => ThicknessToString(thickness),
+ TimeSpan timeSpan => TimeSpanToString(timeSpan),
+ Enum => (int)value,
+ _ => ObjectToDelegate(value)
+ };
+ }
+
///
/// Helper method to serialize objects.
///
diff --git a/src/Microsoft.MobileBlazorBindings/Elements/Element.cs b/src/Microsoft.MobileBlazorBindings/Elements/Element.cs
index 03e446f4..f32ff93f 100644
--- a/src/Microsoft.MobileBlazorBindings/Elements/Element.cs
+++ b/src/Microsoft.MobileBlazorBindings/Elements/Element.cs
@@ -4,6 +4,7 @@
using Microsoft.AspNetCore.Components;
using Microsoft.MobileBlazorBindings.Core;
using MC = Microsoft.Maui.Controls;
+using System.Collections.Generic;
namespace Microsoft.MobileBlazorBindings.Elements
{
@@ -12,6 +13,7 @@ public abstract class Element : NativeControlComponentBase
[Parameter] public string AutomationId { get; set; }
[Parameter] public string ClassId { get; set; }
[Parameter] public string StyleId { get; set; }
+ [Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary AdditionalProperties { get; set; }
public MC.Element NativeControl => ((Handlers.ElementHandler)ElementHandler).ElementControl;
@@ -31,6 +33,13 @@ protected override void RenderAttributes(AttributesBuilder builder)
{
builder.AddAttribute(nameof(StyleId), StyleId);
}
+ if (AdditionalProperties != null)
+ {
+ foreach (var keyValue in AdditionalProperties)
+ {
+ builder.AddAttribute(keyValue.Key, AttributeHelper.ObjectToAttribute(keyValue.Value));
+ }
+ }
}
}
}
diff --git a/src/Microsoft.MobileBlazorBindings/Elements/Grid.cs b/src/Microsoft.MobileBlazorBindings/Elements/Grid.cs
index 7195941a..8b788bbb 100644
--- a/src/Microsoft.MobileBlazorBindings/Elements/Grid.cs
+++ b/src/Microsoft.MobileBlazorBindings/Elements/Grid.cs
@@ -3,11 +3,27 @@
using Microsoft.AspNetCore.Components;
using Microsoft.MobileBlazorBindings.Core;
+using MC = Microsoft.Maui.Controls;
namespace Microsoft.MobileBlazorBindings.Elements
{
public partial class Grid
{
+ static partial void RegisterAdditionalHandlers()
+ {
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Grid.Column",
+ (element, value) => MC.Grid.SetColumn(element, AttributeHelper.GetInt(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Grid.ColumnSpan",
+ (element, value) => MC.Grid.SetColumnSpan(element, AttributeHelper.GetInt(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Grid.Row",
+ (element, value) => MC.Grid.SetRow(element, AttributeHelper.GetInt(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Grid.RowSpan",
+ (element, value) => MC.Grid.SetRowSpan(element, AttributeHelper.GetInt(value)));
+ }
+
///
/// A comma-separated list of column definitions. A column definition can be:
/// Auto-sized with the Auto keyword; A numeric size, such as 80.5; Or a relative size, such as *, 2*, or 3.5*.
diff --git a/src/Microsoft.MobileBlazorBindings/Elements/Handlers/ElementHandler.cs b/src/Microsoft.MobileBlazorBindings/Elements/Handlers/ElementHandler.cs
index a45b5a02..be743b0e 100644
--- a/src/Microsoft.MobileBlazorBindings/Elements/Handlers/ElementHandler.cs
+++ b/src/Microsoft.MobileBlazorBindings/Elements/Handlers/ElementHandler.cs
@@ -51,6 +51,12 @@ public virtual void ApplyAttribute(ulong attributeEventHandlerId, string attribu
public virtual bool ApplyAdditionalAttribute(ulong attributeEventHandlerId, string attributeName, object attributeValue, string attributeEventUpdatesAttributeName)
{
+ if (AttachedPropertyRegistry.AttachedPropertyHandlers.TryGetValue(attributeName, out var handler))
+ {
+ handler(ElementControl, attributeValue);
+ return true;
+ }
+
return false;
}
diff --git a/src/Microsoft.MobileBlazorBindings/Elements/Shell.cs b/src/Microsoft.MobileBlazorBindings/Elements/Shell.cs
index 42fa315c..8dd6d1c6 100644
--- a/src/Microsoft.MobileBlazorBindings/Elements/Shell.cs
+++ b/src/Microsoft.MobileBlazorBindings/Elements/Shell.cs
@@ -12,6 +12,48 @@ namespace Microsoft.MobileBlazorBindings.Elements
{
public partial class Shell : Page
{
+ static partial void RegisterAdditionalHandlers()
+ {
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Shell.NavBarIsVisible",
+ (element, value) => MC.Shell.SetNavBarIsVisible(element, AttributeHelper.GetBool(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Shell.NavBarHasShadow",
+ (element, value) => MC.Shell.SetNavBarHasShadow(element, AttributeHelper.GetBool(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Shell.TabBarIsVisible",
+ (element, value) => MC.Shell.SetTabBarIsVisible(element, AttributeHelper.GetBool(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Shell.BackgroundColor",
+ (element, value) => MC.Shell.SetBackgroundColor(element, AttributeHelper.StringToColor(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Shell.DisabledColor",
+ (element, value) => MC.Shell.SetDisabledColor(element, AttributeHelper.StringToColor(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Shell.ForegroundColor",
+ (element, value) => MC.Shell.SetForegroundColor(element, AttributeHelper.StringToColor(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Shell.TabBarBackgroundColor",
+ (element, value) => MC.Shell.SetTabBarBackgroundColor(element, AttributeHelper.StringToColor(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Shell.TabBarDisabledColor",
+ (element, value) => MC.Shell.SetTabBarDisabledColor(element, AttributeHelper.StringToColor(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Shell.TabBarForegroundColor",
+ (element, value) => MC.Shell.SetTabBarForegroundColor(element, AttributeHelper.StringToColor(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Shell.TabBarTitleColor",
+ (element, value) => MC.Shell.SetTabBarTitleColor(element, AttributeHelper.StringToColor(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Shell.TabBarUnselectedColor",
+ (element, value) => MC.Shell.SetTabBarUnselectedColor(element, AttributeHelper.StringToColor(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Shell.TitleColor",
+ (element, value) => MC.Shell.SetTitleColor(element, AttributeHelper.StringToColor(value)));
+
+ AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Shell.UnselectedColor",
+ (element, value) => MC.Shell.SetUnselectedColor(element, AttributeHelper.StringToColor(value)));
+ }
+
[Parameter] public RenderFragment FlyoutHeader { get; set; }
[Parameter] public EventCallback OnNavigated { get; set; }