From 18591ee16a2dee92c23aa79afbec48c96eb693b7 Mon Sep 17 00:00:00 2001 From: Oleksandr Liakhevych Date: Mon, 21 Nov 2022 16:03:07 +0200 Subject: [PATCH 1/3] Add the support for behaviors --- .../ThirdPartyControlsSample/AppShell.razor | 1 + .../MaskedBehavior.generated.cs | 58 +++++++++++++++++++ .../Pages/CommunityToolkitBehaviors.razor | 19 ++++++ .../Properties/Elements.cs | 1 + .../ComponentWrapperGenerator.cs | 14 ++--- .../Elements/Behavior.generated.cs | 28 +++++++++ .../Elements/VisualElement.cs | 25 ++++++++ .../Properties/AttributeInfo.cs | 1 + 8 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/MaskedBehavior.generated.cs create mode 100644 samples/ThirdPartyControlsSample/Pages/CommunityToolkitBehaviors.razor create mode 100644 src/BlazorBindings.Maui/Elements/Behavior.generated.cs diff --git a/samples/ThirdPartyControlsSample/AppShell.razor b/samples/ThirdPartyControlsSample/AppShell.razor index f89a65c4..bed787fd 100644 --- a/samples/ThirdPartyControlsSample/AppShell.razor +++ b/samples/ThirdPartyControlsSample/AppShell.razor @@ -3,5 +3,6 @@ + \ No newline at end of file diff --git a/samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/MaskedBehavior.generated.cs b/samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/MaskedBehavior.generated.cs new file mode 100644 index 00000000..d1676f8e --- /dev/null +++ b/samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/MaskedBehavior.generated.cs @@ -0,0 +1,58 @@ +// +// This code was generated by a BlazorBindings.Maui component generator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// + +using BlazorBindings.Core; +using BlazorBindings.Maui.Elements; +using CMB = CommunityToolkit.Maui.Behaviors; +using MC = Microsoft.Maui.Controls; +using Microsoft.AspNetCore.Components; +using System.Threading.Tasks; + +namespace BlazorBindings.Maui.Elements.CommunityToolkit.Behaviors +{ + public partial class MaskedBehavior : BlazorBindings.Maui.Elements.Behavior + { + static MaskedBehavior() + { + RegisterAdditionalHandlers(); + } + + [Parameter] public string Mask { get; set; } + [Parameter] public char? UnmaskedCharacter { get; set; } + + public new CMB.MaskedBehavior NativeControl => (CMB.MaskedBehavior)((BindableObject)this).NativeControl; + + protected override CMB.MaskedBehavior CreateNativeElement() => new(); + + protected override void HandleParameter(string name, object value) + { + switch (name) + { + case nameof(Mask): + if (!Equals(Mask, value)) + { + Mask = (string)value; + NativeControl.Mask = Mask; + } + break; + case nameof(UnmaskedCharacter): + if (!Equals(UnmaskedCharacter, value)) + { + UnmaskedCharacter = (char?)value; + NativeControl.UnmaskedCharacter = UnmaskedCharacter ?? (char)CMB.MaskedBehavior.UnmaskedCharacterProperty.DefaultValue; + } + break; + + default: + base.HandleParameter(name, value); + break; + } + } + + static partial void RegisterAdditionalHandlers(); + } +} diff --git a/samples/ThirdPartyControlsSample/Pages/CommunityToolkitBehaviors.razor b/samples/ThirdPartyControlsSample/Pages/CommunityToolkitBehaviors.razor new file mode 100644 index 00000000..cd367eef --- /dev/null +++ b/samples/ThirdPartyControlsSample/Pages/CommunityToolkitBehaviors.razor @@ -0,0 +1,19 @@ +@using BlazorBindings.Maui.Elements.CommunityToolkit.Behaviors + + + + + + + + + + + + + + + +@code { + string value; +} diff --git a/samples/ThirdPartyControlsSample/Properties/Elements.cs b/samples/ThirdPartyControlsSample/Properties/Elements.cs index da83c362..40e67124 100644 --- a/samples/ThirdPartyControlsSample/Properties/Elements.cs +++ b/samples/ThirdPartyControlsSample/Properties/Elements.cs @@ -21,6 +21,7 @@ // CommunityToolkit [assembly: GenerateComponent(typeof(CommunityToolkit.Maui.Views.AvatarView), Exclude = new[] { nameof(CommunityToolkit.Maui.Views.AvatarView.CornerRadius) })] [assembly: GenerateComponent(typeof(CommunityToolkit.Maui.Views.DrawingView))] +[assembly: GenerateComponent(typeof(CommunityToolkit.Maui.Behaviors.MaskedBehavior))] [assembly: GenerateComponent(typeof(CommunityToolkit.Maui.Views.Popup), Exclude = new[] { nameof(CommunityToolkit.Maui.Views.Popup.Anchor) })] // XCalendar diff --git a/src/BlazorBindings.Maui.ComponentGenerator/ComponentWrapperGenerator.cs b/src/BlazorBindings.Maui.ComponentGenerator/ComponentWrapperGenerator.cs index eb214820..6a029e2e 100644 --- a/src/BlazorBindings.Maui.ComponentGenerator/ComponentWrapperGenerator.cs +++ b/src/BlazorBindings.Maui.ComponentGenerator/ComponentWrapperGenerator.cs @@ -283,17 +283,11 @@ public static string GetIdentifierName(string possibleIdentifier) private string GetComponentGroup(INamedTypeSymbol typeToGenerate) { - var assemblyName = typeToGenerate.ContainingAssembly.Name; + var nsName = typeToGenerate.ContainingNamespace.GetFullName(); + var parts = nsName.Split('.') + .Except(new[] { "Maui", "Controls", "Views", "UI", "Microsoft" }, StringComparer.OrdinalIgnoreCase); - if (assemblyName == "Microsoft.Maui.Controls") - { - var nsName = typeToGenerate.ContainingNamespace.GetFullName(); - return nsName == "Microsoft.Maui.Controls" ? "" : nsName.Replace("Microsoft.Maui.Controls.", ""); - } - else - { - return assemblyName.Replace(".Maui", "").Replace(".Views", "").Replace(".UI", "").Replace(".Controls", ""); - } + return string.Join('.', parts); } private string GetComponentNamespace(INamedTypeSymbol typeToGenerate) diff --git a/src/BlazorBindings.Maui/Elements/Behavior.generated.cs b/src/BlazorBindings.Maui/Elements/Behavior.generated.cs new file mode 100644 index 00000000..8a5f766b --- /dev/null +++ b/src/BlazorBindings.Maui/Elements/Behavior.generated.cs @@ -0,0 +1,28 @@ +// +// This code was generated by a BlazorBindings.Maui component generator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// + +using BlazorBindings.Core; +using MC = Microsoft.Maui.Controls; +using Microsoft.AspNetCore.Components; +using System.Threading.Tasks; + +namespace BlazorBindings.Maui.Elements +{ + public abstract partial class Behavior : BindableObject + { + static Behavior() + { + RegisterAdditionalHandlers(); + } + + public new MC.Behavior NativeControl => (MC.Behavior)((BindableObject)this).NativeControl; + + + + static partial void RegisterAdditionalHandlers(); + } +} diff --git a/src/BlazorBindings.Maui/Elements/VisualElement.cs b/src/BlazorBindings.Maui/Elements/VisualElement.cs index 4e182aef..c5732784 100644 --- a/src/BlazorBindings.Maui/Elements/VisualElement.cs +++ b/src/BlazorBindings.Maui/Elements/VisualElement.cs @@ -1,16 +1,29 @@ +using BlazorBindings.Core; +using BlazorBindings.Maui.Elements.Handlers; using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Rendering; +using Microsoft.Maui; using Microsoft.Maui.Graphics; +using MC = Microsoft.Maui.Controls; namespace BlazorBindings.Maui.Elements { public abstract partial class VisualElement { + static partial void RegisterAdditionalHandlers() + { + ElementHandlerRegistry.RegisterPropertyContentHandler(nameof(Behaviors), + (renderer, parent, component) => new ListContentPropertyHandler(x => x.Behaviors)); + } + // This property is defined manually to allow to override it's behavior (see Shell). /// /// Gets or sets the color which will fill the background of a VisualElement. /// [Parameter] public Color BackgroundColor { get; set; } + [Parameter] public RenderFragment Behaviors { get; set; } + protected override bool HandleAdditionalParameter(string name, object value) { if (name == nameof(BackgroundColor)) @@ -22,8 +35,20 @@ protected override bool HandleAdditionalParameter(string name, object value) } return true; } + else if (name == nameof(Behaviors)) + { + Behaviors = (RenderFragment)value; + return true; + } return base.HandleAdditionalParameter(name, value); } + + protected override void RenderAdditionalPartialElementContent(RenderTreeBuilder builder, ref int sequence) + { + base.RenderAdditionalPartialElementContent(builder, ref sequence); + + RenderTreeBuilderHelper.AddContentProperty(builder, sequence++, typeof(VisualElement), Behaviors); + } } } diff --git a/src/BlazorBindings.Maui/Properties/AttributeInfo.cs b/src/BlazorBindings.Maui/Properties/AttributeInfo.cs index 0a8a2ada..d3b64a3d 100644 --- a/src/BlazorBindings.Maui/Properties/AttributeInfo.cs +++ b/src/BlazorBindings.Maui/Properties/AttributeInfo.cs @@ -11,6 +11,7 @@ [assembly: GenerateComponent(typeof(ActivityIndicator))] [assembly: GenerateComponent(typeof(BaseMenuItem))] [assembly: GenerateComponent(typeof(BaseShellItem))] +[assembly: GenerateComponent(typeof(Behavior))] [assembly: GenerateComponent(typeof(Border))] [assembly: GenerateComponent(typeof(BoxView))] [assembly: GenerateComponent(typeof(Brush))] From 18748c539057dd2caebcd77bea395ada2296ceef Mon Sep 17 00:00:00 2001 From: Oleksandr Liakhevych Date: Tue, 22 Nov 2022 01:18:17 +0200 Subject: [PATCH 2/3] More samples --- .../StatusBarBehavior.generated.cs | 60 +++++++++++++++++ .../UserStoppedTypingBehavior.cs | 27 ++++++++ .../UserStoppedTypingBehavior.generated.cs | 66 +++++++++++++++++++ .../Pages/CommunityToolkitBehaviors.razor | 66 +++++++++++++++---- .../Properties/Elements.cs | 7 +- .../Elements/Input/EventCallbackCommand.cs | 14 +++- 6 files changed, 222 insertions(+), 18 deletions(-) create mode 100644 samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/StatusBarBehavior.generated.cs create mode 100644 samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/UserStoppedTypingBehavior.cs create mode 100644 samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/UserStoppedTypingBehavior.generated.cs diff --git a/samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/StatusBarBehavior.generated.cs b/samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/StatusBarBehavior.generated.cs new file mode 100644 index 00000000..29f9b6ed --- /dev/null +++ b/samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/StatusBarBehavior.generated.cs @@ -0,0 +1,60 @@ +// +// This code was generated by a BlazorBindings.Maui component generator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// + +using BlazorBindings.Core; +using BlazorBindings.Maui.Elements; +using CMB = CommunityToolkit.Maui.Behaviors; +using CommunityToolkit.Maui.Core; +using MC = Microsoft.Maui.Controls; +using Microsoft.AspNetCore.Components; +using Microsoft.Maui.Graphics; +using System.Threading.Tasks; + +namespace BlazorBindings.Maui.Elements.CommunityToolkit.Behaviors +{ + public partial class StatusBarBehavior : BlazorBindings.Maui.Elements.Behavior + { + static StatusBarBehavior() + { + RegisterAdditionalHandlers(); + } + + [Parameter] public Color StatusBarColor { get; set; } + [Parameter] public StatusBarStyle? StatusBarStyle { get; set; } + + public new CMB.StatusBarBehavior NativeControl => (CMB.StatusBarBehavior)((BindableObject)this).NativeControl; + + protected override CMB.StatusBarBehavior CreateNativeElement() => new(); + + protected override void HandleParameter(string name, object value) + { + switch (name) + { + case nameof(StatusBarColor): + if (!Equals(StatusBarColor, value)) + { + StatusBarColor = (Color)value; + NativeControl.StatusBarColor = StatusBarColor; + } + break; + case nameof(StatusBarStyle): + if (!Equals(StatusBarStyle, value)) + { + StatusBarStyle = (StatusBarStyle?)value; + NativeControl.StatusBarStyle = StatusBarStyle ?? (StatusBarStyle)CMB.StatusBarBehavior.StatusBarStyleProperty.DefaultValue; + } + break; + + default: + base.HandleParameter(name, value); + break; + } + } + + static partial void RegisterAdditionalHandlers(); + } +} diff --git a/samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/UserStoppedTypingBehavior.cs b/samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/UserStoppedTypingBehavior.cs new file mode 100644 index 00000000..bf8d6634 --- /dev/null +++ b/samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/UserStoppedTypingBehavior.cs @@ -0,0 +1,27 @@ +using BlazorBindings.Maui.Elements.Input; +using Microsoft.AspNetCore.Components; + +namespace BlazorBindings.Maui.Elements.CommunityToolkit.Behaviors +{ + public partial class UserStoppedTypingBehavior + { + [Parameter] public EventCallback Command { get; set; } + + protected override bool HandleAdditionalParameter(string name, object value) + { + if (name == nameof(Command)) + { + if (!Equals(Command, value)) + { + Command = (EventCallback)value; + NativeControl.Command = Command.HasDelegate + ? new EventCallbackCommand(value => InvokeEventCallback(Command, (string)value)) + : null; + } + return true; + } + + return base.HandleAdditionalParameter(name, value); + } + } +} diff --git a/samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/UserStoppedTypingBehavior.generated.cs b/samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/UserStoppedTypingBehavior.generated.cs new file mode 100644 index 00000000..f6031f3d --- /dev/null +++ b/samples/ThirdPartyControlsSample/Elements/CommunityToolkit.Behaviors/UserStoppedTypingBehavior.generated.cs @@ -0,0 +1,66 @@ +// +// This code was generated by a BlazorBindings.Maui component generator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// + +using BlazorBindings.Core; +using BlazorBindings.Maui.Elements; +using CMB = CommunityToolkit.Maui.Behaviors; +using MC = Microsoft.Maui.Controls; +using Microsoft.AspNetCore.Components; +using System.Threading.Tasks; + +namespace BlazorBindings.Maui.Elements.CommunityToolkit.Behaviors +{ + public partial class UserStoppedTypingBehavior : BlazorBindings.Maui.Elements.Behavior + { + static UserStoppedTypingBehavior() + { + RegisterAdditionalHandlers(); + } + + [Parameter] public int? MinimumLengthThreshold { get; set; } + [Parameter] public bool? ShouldDismissKeyboardAutomatically { get; set; } + [Parameter] public int? StoppedTypingTimeThreshold { get; set; } + + public new CMB.UserStoppedTypingBehavior NativeControl => (CMB.UserStoppedTypingBehavior)((BindableObject)this).NativeControl; + + protected override CMB.UserStoppedTypingBehavior CreateNativeElement() => new(); + + protected override void HandleParameter(string name, object value) + { + switch (name) + { + case nameof(MinimumLengthThreshold): + if (!Equals(MinimumLengthThreshold, value)) + { + MinimumLengthThreshold = (int?)value; + NativeControl.MinimumLengthThreshold = MinimumLengthThreshold ?? (int)CMB.UserStoppedTypingBehavior.MinimumLengthThresholdProperty.DefaultValue; + } + break; + case nameof(ShouldDismissKeyboardAutomatically): + if (!Equals(ShouldDismissKeyboardAutomatically, value)) + { + ShouldDismissKeyboardAutomatically = (bool?)value; + NativeControl.ShouldDismissKeyboardAutomatically = ShouldDismissKeyboardAutomatically ?? (bool)CMB.UserStoppedTypingBehavior.ShouldDismissKeyboardAutomaticallyProperty.DefaultValue; + } + break; + case nameof(StoppedTypingTimeThreshold): + if (!Equals(StoppedTypingTimeThreshold, value)) + { + StoppedTypingTimeThreshold = (int?)value; + NativeControl.StoppedTypingTimeThreshold = StoppedTypingTimeThreshold ?? (int)CMB.UserStoppedTypingBehavior.StoppedTypingTimeThresholdProperty.DefaultValue; + } + break; + + default: + base.HandleParameter(name, value); + break; + } + } + + static partial void RegisterAdditionalHandlers(); + } +} diff --git a/samples/ThirdPartyControlsSample/Pages/CommunityToolkitBehaviors.razor b/samples/ThirdPartyControlsSample/Pages/CommunityToolkitBehaviors.razor index cd367eef..66fcca7e 100644 --- a/samples/ThirdPartyControlsSample/Pages/CommunityToolkitBehaviors.razor +++ b/samples/ThirdPartyControlsSample/Pages/CommunityToolkitBehaviors.razor @@ -1,19 +1,59 @@ @using BlazorBindings.Maui.Elements.CommunityToolkit.Behaviors - - - - - - - - - - - - + + + + + + + + + +