Coder Social home page Coder Social logo

dreamescaper / blazorbindings.maui Goto Github PK

View Code? Open in Web Editor NEW

This project forked from dotnet/mobileblazorbindings

240.0 21.0 16.0 7.8 MB

MAUI Blazor Bindings - Build native and hybrid MAUI apps with Blazor

License: MIT License

C# 90.63% HTML 9.37%
blazor dotnet maui

blazorbindings.maui's Introduction

BlazorBindings.Maui

Nuget Join Discord

Getting Started

Check out the documentation for how to build your first app: https://dreamescaper.github.io/MobileBlazorBindingsDocs

What is it?

Maui Blazor Bindings enable developers to build native and hybrid mobile apps using C# and .NET for Android, iOS, Windows, macOS, and Tizen using familiar web programming patterns. This means you can use the Blazor programming model and Razor syntax to define UI components and behaviors of an application. The UI components that are included are based on MAUI native UI controls, which results in beautiful native mobile apps.

Here is a sample Counter component that renders native UI, which may look familiar to Blazor developers, that increments a value on each button press:

<StackLayout>
    <Label FontSize="30">You pressed @count times </Label>
    <Button Text="+1" OnClick="@HandleClick" />
</StackLayout>

@code {
    int count;

    void HandleClick()
    {
        count++;
    }
}

Notice that the Blazor model is present with code sitting side by side the user interface markup that leverages Razor syntax with mobile specific components. This will feel very natural for any web developer that has ever used Razor syntax in the past. Now with the Experimental Mobile Blazor Bindings you can leverage your existing web skills and knowledge to build native and hybrid mobile apps using C# and .NET for Android, iOS, Windows, macOS, and Tizen.

Here is the code above running in the Android Emulator:

Clicking increment button in Android emulator

About this repository

This repository is a fork of Microsoft's Experimental MobileBlazorBindings, which I decided to fork and maintain separately. If at any point of time Microsoft developers decide to push that repository moving forward, I'll gladly contribute all of my changes to the original repository.

Code of Conduct

This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community.

For more information, see the .NET Foundation Code of Conduct.

Thank you!

blazorbindings.maui's People

Contributors

0x414c49 avatar angelobelchior avatar danroth27 avatar dreamescaper avatar eilon avatar jonlipsky avatar jspuij avatar kahbazi avatar kukks avatar lachlanwgordon avatar mattleibow avatar myroot avatar rookiejava avatar stevesandersonms avatar thecakemonster avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blazorbindings.maui's Issues

Events naming - does it make sense?

Currently for all the eventCallback we use the naming with "On" prefix (e.g. Scrolled -> OnScrolled, Clicked -> OnClick). I'm not really sure why it was made this way. Does is make any sense? Would it be better to use the same name as Maui events?

Revisit GestureRecognizers approach

Currently GestureRecognizers are implemented so it would look similar to MAUI's or Xamarin.Forms' XAML syntax:

<Label Text="Tap Me">
   <TapGestureRecognizer OnTap="ProcessTap" />
</Label>

This implementation has a couple of issues.

  • Currently it is not supported by components, which do not allow ChildContent, e.g. Image.
  • It looks strange if your component has other content properties.
<ContentPage>
    <Background>
        <LinearGradientBrush EndPoint="new Point(0,1)">
            <GradientStop Color="Colors.LightSkyBlue" Offset="0" />
            <GradientStop Color="Colors.White" Offset="1" />
        </LinearGradientBrush>
    </Background>

    <ChildContent>
              <TapGestureRecognizer OnTap="ProcessTap" />   // <--------- why here?...

               <ScrollView>
                ...
               </ScrollView>
     </ChildContent>
</ContentPage>
  • It is verbose and doesn't feel natural for Blazor.

Instead, I suggest to implement approach similar to https://www.mrgestures.com/. Add events like OnTap, OnDoubleTap, OnPinch etc to View component.

<Label Text="Tap Me" OnTap="ProcessTap" />

It will still be implemented as GestureRecognizers underneath.

Add Shell attached properties to Page component

Currently Shell attached properties are supported, but they are quite hard to find.

Since Shell is the recommended approach by Maui team, it probably makes sense to add those as a regular properties.
They will be ignored if Shell is not used.
If NavigationPage is used, we can map matching properties.

Allow to replace root component

@if(_someCondition)
{
   <MainPage1 />
}
else
{
   <MainPage2 />
}

Currently the component above does not make much sense - the Renderer wouldn't replace the page is has set before. It seems like an edge case, but it blocks the case with setting a global ErrorBoundary (which would replace the MainPage with some error page).

It should be supported for both MainPage and Navigation cases.

Question: Class libraries

Thanks for this library. I am just evaluating it at the moment, but it looks great!

Do you have instructions for how I can create a class library? I don't see a template for it, so this is what I did

1: Created another new app
2: Reduced the csproj to the following

<Project Sdk="Microsoft.NET.Sdk.Razor">

	<PropertyGroup>
		<TargetFrameworks>net7.0-android;net7.0-ios;net7.0-maccatalyst</TargetFrameworks>
		<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net7.0-windows10.0.19041.0</TargetFrameworks>
		<RootNamespace>DSMauiComponents</RootNamespace>
		<UseMaui>true</UseMaui>
		<EnableDefaultCssItems>false</EnableDefaultCssItems>

		<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
		<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.0</SupportedOSPlatformVersion>
		<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">23.0</SupportedOSPlatformVersion>
		<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
		<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
	</PropertyGroup>

	<ItemGroup>
		<PackageReference Include="BlazorBindings.Maui" Version="0.10.40-preview" />
	</ItemGroup>

</Project>
  1. Referenced it from my main app

When I use a component in that class library I get an error telling me there can only be one root element in the app, even though it is added inside the VerticalStackLayout in the default main page (just about the counter button).

Support for third party control out the box.

One of my reservations about how BlazorBindings was implemented is how much work it will take to bring third party controls onboard.

I have a development that takes another approach entirely by allowing any third party library to work with BlazorBindings. It uses a generator to generate binding codes bridge between the controls and Blazor component.

This is what typical generated component looks like

    public partial class Button : ComponentToMAUIBridge<Microsoft.Maui.Controls.Button, Button>
    {
        public Button()
        {
        }
        public Button(Microsoft.Maui.Controls.Button _element):base(_element)
        {
        }

		[Parameter] public System.EventHandler Clicked { set => P.Clicked += value; }
		EventCallback _onClicked;
		[Parameter] public EventCallback OnClicked { set { if (!_onClicked.HasDelegate) { P.Clicked += (s, e) => _onClicked.InvokeAsync(e); } _onClicked = value; } }
		[Parameter] public System.EventHandler Pressed { set => P.Pressed += value; }
		EventCallback _onPressed;
		[Parameter] public EventCallback OnPressed { set { if (!_onPressed.HasDelegate) { P.Pressed += (s, e) => _onPressed.InvokeAsync(e); } _onPressed = value; } }
		[Parameter] public System.EventHandler Released { set => P.Released += value; }
		EventCallback _onReleased;
		[Parameter] public EventCallback OnReleased { set { if (!_onReleased.HasDelegate) { P.Released += (s, e) => _onReleased.InvokeAsync(e); } _onReleased = value; } }
		[Parameter] public System.EventHandler ChildrenReordered { set => P.ChildrenReordered += value; }
		EventCallback _onChildrenReordered;
		[Parameter] public EventCallback OnChildrenReordered { set { if (!_onChildrenReordered.HasDelegate) { P.ChildrenReordered += (s, e) => _onChildrenReordered.InvokeAsync(e); } _onChildrenReordered = value; } }
		[Parameter] public System.EventHandler<Microsoft.Maui.Controls.FocusEventArgs> Focused { set => P.Focused += value; }
		EventCallback<Microsoft.Maui.Controls.FocusEventArgs> _onFocused;
		[Parameter] public EventCallback<Microsoft.Maui.Controls.FocusEventArgs> OnFocused { set { if (!_onFocused.HasDelegate) { P.Focused += (s, e) => _onFocused.InvokeAsync(e); } _onFocused = value; } }
		[Parameter] public System.EventHandler MeasureInvalidated { set => P.MeasureInvalidated += value; }
		EventCallback _onMeasureInvalidated;
		[Parameter] public EventCallback OnMeasureInvalidated { set { if (!_onMeasureInvalidated.HasDelegate) { P.MeasureInvalidated += (s, e) => _onMeasureInvalidated.InvokeAsync(e); } _onMeasureInvalidated = value; } }
		[Parameter] public System.EventHandler SizeChanged { set => P.SizeChanged += value; }
		EventCallback _onSizeChanged;
		[Parameter] public EventCallback OnSizeChanged { set { if (!_onSizeChanged.HasDelegate) { P.SizeChanged += (s, e) => _onSizeChanged.InvokeAsync(e); } _onSizeChanged = value; } }
		[Parameter] public System.EventHandler<Microsoft.Maui.Controls.FocusEventArgs> Unfocused { set => P.Unfocused += value; }
		EventCallback<Microsoft.Maui.Controls.FocusEventArgs> _onUnfocused;
		[Parameter] public EventCallback<Microsoft.Maui.Controls.FocusEventArgs> OnUnfocused { set { if (!_onUnfocused.HasDelegate) { P.Unfocused += (s, e) => _onUnfocused.InvokeAsync(e); } _onUnfocused = value; } }
		[Parameter] public System.EventHandler<Microsoft.Maui.Controls.Internals.EventArg<Microsoft.Maui.Controls.VisualElement>> BatchCommitted { set => P.BatchCommitted += value; }
		EventCallback<Microsoft.Maui.Controls.Internals.EventArg<Microsoft.Maui.Controls.VisualElement>> _onBatchCommitted;
		[Parameter] public EventCallback<Microsoft.Maui.Controls.Internals.EventArg<Microsoft.Maui.Controls.VisualElement>> OnBatchCommitted { set { if (!_onBatchCommitted.HasDelegate) { P.BatchCommitted += (s, e) => _onBatchCommitted.InvokeAsync(e); } _onBatchCommitted = value; } }
		[Parameter] public System.EventHandler<Microsoft.Maui.Controls.VisualElement.FocusRequestArgs> FocusChangeRequested { set => P.FocusChangeRequested += value; }
		EventCallback<Microsoft.Maui.Controls.VisualElement.FocusRequestArgs> _onFocusChangeRequested;
		[Parameter] public EventCallback<Microsoft.Maui.Controls.VisualElement.FocusRequestArgs> OnFocusChangeRequested { set { if (!_onFocusChangeRequested.HasDelegate) { P.FocusChangeRequested += (s, e) => _onFocusChangeRequested.InvokeAsync(e); } _onFocusChangeRequested = value; } }
		[Parameter] public System.EventHandler Loaded { set => P.Loaded += value; }
		EventCallback _onLoaded;
		[Parameter] public EventCallback OnLoaded { set { if (!_onLoaded.HasDelegate) { P.Loaded += (s, e) => _onLoaded.InvokeAsync(e); } _onLoaded = value; } }
		[Parameter] public System.EventHandler Unloaded { set => P.Unloaded += value; }
		EventCallback _onUnloaded;
		[Parameter] public EventCallback OnUnloaded { set { if (!_onUnloaded.HasDelegate) { P.Unloaded += (s, e) => _onUnloaded.InvokeAsync(e); } _onUnloaded = value; } }
		[Parameter] public System.EventHandler<Microsoft.Maui.Controls.ElementEventArgs> ChildAdded { set => P.ChildAdded += value; }
		EventCallback<Microsoft.Maui.Controls.ElementEventArgs> _onChildAdded;
		[Parameter] public EventCallback<Microsoft.Maui.Controls.ElementEventArgs> OnChildAdded { set { if (!_onChildAdded.HasDelegate) { P.ChildAdded += (s, e) => _onChildAdded.InvokeAsync(e); } _onChildAdded = value; } }
		[Parameter] public System.EventHandler<Microsoft.Maui.Controls.ElementEventArgs> ChildRemoved { set => P.ChildRemoved += value; }
		EventCallback<Microsoft.Maui.Controls.ElementEventArgs> _onChildRemoved;
		[Parameter] public EventCallback<Microsoft.Maui.Controls.ElementEventArgs> OnChildRemoved { set { if (!_onChildRemoved.HasDelegate) { P.ChildRemoved += (s, e) => _onChildRemoved.InvokeAsync(e); } _onChildRemoved = value; } }
		[Parameter] public System.EventHandler<Microsoft.Maui.Controls.ElementEventArgs> DescendantAdded { set => P.DescendantAdded += value; }
		EventCallback<Microsoft.Maui.Controls.ElementEventArgs> _onDescendantAdded;
		[Parameter] public EventCallback<Microsoft.Maui.Controls.ElementEventArgs> OnDescendantAdded { set { if (!_onDescendantAdded.HasDelegate) { P.DescendantAdded += (s, e) => _onDescendantAdded.InvokeAsync(e); } _onDescendantAdded = value; } }
		[Parameter] public System.EventHandler<Microsoft.Maui.Controls.ElementEventArgs> DescendantRemoved { set => P.DescendantRemoved += value; }
		EventCallback<Microsoft.Maui.Controls.ElementEventArgs> _onDescendantRemoved;
		[Parameter] public EventCallback<Microsoft.Maui.Controls.ElementEventArgs> OnDescendantRemoved { set { if (!_onDescendantRemoved.HasDelegate) { P.DescendantRemoved += (s, e) => _onDescendantRemoved.InvokeAsync(e); } _onDescendantRemoved = value; } }
		[Parameter] public System.EventHandler<Microsoft.Maui.Controls.ParentChangingEventArgs> ParentChanging { set => P.ParentChanging += value; }
		EventCallback<Microsoft.Maui.Controls.ParentChangingEventArgs> _onParentChanging;
		[Parameter] public EventCallback<Microsoft.Maui.Controls.ParentChangingEventArgs> OnParentChanging { set { if (!_onParentChanging.HasDelegate) { P.ParentChanging += (s, e) => _onParentChanging.InvokeAsync(e); } _onParentChanging = value; } }
		[Parameter] public System.EventHandler ParentChanged { set => P.ParentChanged += value; }
		EventCallback _onParentChanged;
		[Parameter] public EventCallback OnParentChanged { set { if (!_onParentChanged.HasDelegate) { P.ParentChanged += (s, e) => _onParentChanged.InvokeAsync(e); } _onParentChanged = value; } }
		[Parameter] public System.EventHandler<Microsoft.Maui.Controls.HandlerChangingEventArgs> HandlerChanging { set => P.HandlerChanging += value; }
		EventCallback<Microsoft.Maui.Controls.HandlerChangingEventArgs> _onHandlerChanging;
		[Parameter] public EventCallback<Microsoft.Maui.Controls.HandlerChangingEventArgs> OnHandlerChanging { set { if (!_onHandlerChanging.HasDelegate) { P.HandlerChanging += (s, e) => _onHandlerChanging.InvokeAsync(e); } _onHandlerChanging = value; } }
		[Parameter] public System.EventHandler HandlerChanged { set => P.HandlerChanged += value; }
		EventCallback _onHandlerChanged;
		[Parameter] public EventCallback OnHandlerChanged { set { if (!_onHandlerChanged.HasDelegate) { P.HandlerChanged += (s, e) => _onHandlerChanged.InvokeAsync(e); } _onHandlerChanged = value; } }
		[Parameter] public System.EventHandler BindingContextChanged { set => P.BindingContextChanged += value; }
		EventCallback _onBindingContextChanged;
		[Parameter] public EventCallback OnBindingContextChanged { set { if (!_onBindingContextChanged.HasDelegate) { P.BindingContextChanged += (s, e) => _onBindingContextChanged.InvokeAsync(e); } _onBindingContextChanged = value; } }
		[Parameter] public Microsoft.Maui.Thickness Padding { set => P.Padding = value; get => P.Padding; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindPadding { set { P.SetBinding(Microsoft.Maui.Controls.Button.PaddingProperty, value); } }
		[Parameter] public Microsoft.Maui.LineBreakMode LineBreakMode { set => P.LineBreakMode = value; get => P.LineBreakMode; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindLineBreakMode { set { P.SetBinding(Microsoft.Maui.Controls.Button.LineBreakModeProperty, value); } }
		[Parameter] public Microsoft.Maui.Graphics.Color BorderColor { set => P.BorderColor = value; get => P.BorderColor; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindBorderColor { set { P.SetBinding(Microsoft.Maui.Controls.Button.BorderColorProperty, value); } }
		[Parameter] public System.Int32 CornerRadius { set => P.CornerRadius = value; get => P.CornerRadius; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindCornerRadius { set { P.SetBinding(Microsoft.Maui.Controls.Button.CornerRadiusProperty, value); } }
		[Parameter] public System.Double BorderWidth { set => P.BorderWidth = value; get => P.BorderWidth; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindBorderWidth { set { P.SetBinding(Microsoft.Maui.Controls.Button.BorderWidthProperty, value); } }
		[Parameter] public Microsoft.Maui.Controls.Button.ButtonContentLayout ContentLayout { set => P.ContentLayout = value; get => P.ContentLayout; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindContentLayout { set { P.SetBinding(Microsoft.Maui.Controls.Button.ContentLayoutProperty, value); } }
		[Parameter] public System.Windows.Input.ICommand Command { set => P.Command = value; get => P.Command; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindCommand { set { P.SetBinding(Microsoft.Maui.Controls.Button.CommandProperty, value); } }
		[Parameter] public EventCallback OnCommand { set { Command = new Microsoft.Maui.Controls.Command(async () => { await value.InvokeAsync(this); }); } }
		[Parameter] public System.Object CommandParameter { set => P.CommandParameter = value; get => P.CommandParameter; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindCommandParameter { set { P.SetBinding(Microsoft.Maui.Controls.Button.CommandParameterProperty, value); } }
		[Parameter] public Microsoft.Maui.Controls.ImageSource ImageSource { set => P.ImageSource = value; get => P.ImageSource; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindImageSource { set { P.SetBinding(Microsoft.Maui.Controls.Button.ImageSourceProperty, value); } }
		[Parameter] public System.String Text { set => P.Text = value; get => P.Text; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindText { set { P.SetBinding(Microsoft.Maui.Controls.Button.TextProperty, value); } }
		[Parameter] public Microsoft.Maui.Graphics.Color TextColor { set => P.TextColor = value; get => P.TextColor; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindTextColor { set { P.SetBinding(Microsoft.Maui.Controls.Button.TextColorProperty, value); } }
		[Parameter] public System.Double CharacterSpacing { set => P.CharacterSpacing = value; get => P.CharacterSpacing; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindCharacterSpacing { set { P.SetBinding(Microsoft.Maui.Controls.Button.CharacterSpacingProperty, value); } }
		[Parameter] public Microsoft.Maui.Controls.FontAttributes FontAttributes { set => P.FontAttributes = value; get => P.FontAttributes; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindFontAttributes { set { P.SetBinding(Microsoft.Maui.Controls.Button.FontAttributesProperty, value); } }
		[Parameter] public System.String FontFamily { set => P.FontFamily = value; get => P.FontFamily; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindFontFamily { set { P.SetBinding(Microsoft.Maui.Controls.Button.FontFamilyProperty, value); } }
		[Parameter] public System.Double FontSize { set => P.FontSize = value; get => P.FontSize; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindFontSize { set { P.SetBinding(Microsoft.Maui.Controls.Button.FontSizeProperty, value); } }
		[Parameter] public System.Boolean FontAutoScalingEnabled { set => P.FontAutoScalingEnabled = value; get => P.FontAutoScalingEnabled; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindFontAutoScalingEnabled { set { P.SetBinding(Microsoft.Maui.Controls.Button.FontAutoScalingEnabledProperty, value); } }
		[Parameter] public Microsoft.Maui.TextTransform TextTransform { set => P.TextTransform = value; get => P.TextTransform; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindTextTransform { set { P.SetBinding(Microsoft.Maui.Controls.Button.TextTransformProperty, value); } }
		[Parameter] public Microsoft.Maui.Controls.LayoutOptions HorizontalOptions { set => P.HorizontalOptions = value; get => P.HorizontalOptions; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindHorizontalOptions { set { P.SetBinding(Microsoft.Maui.Controls.Button.HorizontalOptionsProperty, value); } }
		[Parameter] public Microsoft.Maui.Thickness Margin { set => P.Margin = value; get => P.Margin; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindMargin { set { P.SetBinding(Microsoft.Maui.Controls.Button.MarginProperty, value); } }
		[Parameter] public Microsoft.Maui.Controls.LayoutOptions VerticalOptions { set => P.VerticalOptions = value; get => P.VerticalOptions; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindVerticalOptions { set { P.SetBinding(Microsoft.Maui.Controls.Button.VerticalOptionsProperty, value); } }
		[Parameter] public Microsoft.Maui.Graphics.Rect Frame { set => P.Frame = value; get => P.Frame; }
		[Parameter] public Microsoft.Maui.IViewHandler Handler { set => P.Handler = value; get => P.Handler; }
		[Parameter] public Microsoft.Maui.Controls.Shadow Shadow { set => P.Shadow = value; get => P.Shadow; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindShadow { set { P.SetBinding(Microsoft.Maui.Controls.Button.ShadowProperty, value); } }
		[Parameter] public System.Int32 ZIndex { set => P.ZIndex = value; get => P.ZIndex; }
		[Parameter] public Microsoft.Maui.Controls.IVisual Visual { set => P.Visual = value; get => P.Visual; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindVisual { set { P.SetBinding(Microsoft.Maui.Controls.Button.VisualProperty, value); } }
		[Parameter] public Microsoft.Maui.FlowDirection FlowDirection { set => P.FlowDirection = value; get => P.FlowDirection; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindFlowDirection { set { P.SetBinding(Microsoft.Maui.Controls.Button.FlowDirectionProperty, value); } }
		[Parameter] public System.Double AnchorX { set => P.AnchorX = value; get => P.AnchorX; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindAnchorX { set { P.SetBinding(Microsoft.Maui.Controls.Button.AnchorXProperty, value); } }
		[Parameter] public System.Double AnchorY { set => P.AnchorY = value; get => P.AnchorY; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindAnchorY { set { P.SetBinding(Microsoft.Maui.Controls.Button.AnchorYProperty, value); } }
		[Parameter] public Microsoft.Maui.Graphics.Color BackgroundColor { set => P.BackgroundColor = value; get => P.BackgroundColor; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindBackgroundColor { set { P.SetBinding(Microsoft.Maui.Controls.Button.BackgroundColorProperty, value); } }
		[Parameter] public Microsoft.Maui.Controls.Brush Background { set => P.Background = value; get => P.Background; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindBackground { set { P.SetBinding(Microsoft.Maui.Controls.Button.BackgroundProperty, value); } }
		[Parameter] public System.Double HeightRequest { set => P.HeightRequest = value; get => P.HeightRequest; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindHeightRequest { set { P.SetBinding(Microsoft.Maui.Controls.Button.HeightRequestProperty, value); } }
		[Parameter] public System.Boolean InputTransparent { set => P.InputTransparent = value; get => P.InputTransparent; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindInputTransparent { set { P.SetBinding(Microsoft.Maui.Controls.Button.InputTransparentProperty, value); } }
		[Parameter] public System.Boolean IsEnabled { set => P.IsEnabled = value; get => P.IsEnabled; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindIsEnabled { set { P.SetBinding(Microsoft.Maui.Controls.Button.IsEnabledProperty, value); } }
		[Parameter] public System.Boolean IsVisible { set => P.IsVisible = value; get => P.IsVisible; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindIsVisible { set { P.SetBinding(Microsoft.Maui.Controls.Button.IsVisibleProperty, value); } }
		[Parameter] public System.Double MinimumHeightRequest { set => P.MinimumHeightRequest = value; get => P.MinimumHeightRequest; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindMinimumHeightRequest { set { P.SetBinding(Microsoft.Maui.Controls.Button.MinimumHeightRequestProperty, value); } }
		[Parameter] public System.Double MinimumWidthRequest { set => P.MinimumWidthRequest = value; get => P.MinimumWidthRequest; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindMinimumWidthRequest { set { P.SetBinding(Microsoft.Maui.Controls.Button.MinimumWidthRequestProperty, value); } }
		[Parameter] public System.Double MaximumHeightRequest { set => P.MaximumHeightRequest = value; get => P.MaximumHeightRequest; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindMaximumHeightRequest { set { P.SetBinding(Microsoft.Maui.Controls.Button.MaximumHeightRequestProperty, value); } }
		[Parameter] public System.Double MaximumWidthRequest { set => P.MaximumWidthRequest = value; get => P.MaximumWidthRequest; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindMaximumWidthRequest { set { P.SetBinding(Microsoft.Maui.Controls.Button.MaximumWidthRequestProperty, value); } }
		[Parameter] public System.Double Opacity { set => P.Opacity = value; get => P.Opacity; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindOpacity { set { P.SetBinding(Microsoft.Maui.Controls.Button.OpacityProperty, value); } }
		[Parameter] public System.Double Rotation { set => P.Rotation = value; get => P.Rotation; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindRotation { set { P.SetBinding(Microsoft.Maui.Controls.Button.RotationProperty, value); } }
		[Parameter] public System.Double RotationX { set => P.RotationX = value; get => P.RotationX; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindRotationX { set { P.SetBinding(Microsoft.Maui.Controls.Button.RotationXProperty, value); } }
		[Parameter] public System.Double RotationY { set => P.RotationY = value; get => P.RotationY; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindRotationY { set { P.SetBinding(Microsoft.Maui.Controls.Button.RotationYProperty, value); } }
		[Parameter] public System.Double Scale { set => P.Scale = value; get => P.Scale; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindScale { set { P.SetBinding(Microsoft.Maui.Controls.Button.ScaleProperty, value); } }
		[Parameter] public System.Double ScaleX { set => P.ScaleX = value; get => P.ScaleX; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindScaleX { set { P.SetBinding(Microsoft.Maui.Controls.Button.ScaleXProperty, value); } }
		[Parameter] public System.Double ScaleY { set => P.ScaleY = value; get => P.ScaleY; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindScaleY { set { P.SetBinding(Microsoft.Maui.Controls.Button.ScaleYProperty, value); } }
		[Parameter] public System.Double TranslationX { set => P.TranslationX = value; get => P.TranslationX; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindTranslationX { set { P.SetBinding(Microsoft.Maui.Controls.Button.TranslationXProperty, value); } }
		[Parameter] public System.Double TranslationY { set => P.TranslationY = value; get => P.TranslationY; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindTranslationY { set { P.SetBinding(Microsoft.Maui.Controls.Button.TranslationYProperty, value); } }
		[Parameter] public System.Double WidthRequest { set => P.WidthRequest = value; get => P.WidthRequest; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindWidthRequest { set { P.SetBinding(Microsoft.Maui.Controls.Button.WidthRequestProperty, value); } }
		[Parameter] public Microsoft.Maui.Controls.Shapes.Geometry Clip { set => P.Clip = value; get => P.Clip; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindClip { set { P.SetBinding(Microsoft.Maui.Controls.Button.ClipProperty, value); } }
		[Parameter] public System.Boolean DisableLayout { set => P.DisableLayout = value; get => P.DisableLayout; }
		[Parameter] public System.Boolean IsInPlatformLayout { set => P.IsInPlatformLayout = value; get => P.IsInPlatformLayout; }
		[Parameter] public System.Boolean IsPlatformStateConsistent { set => P.IsPlatformStateConsistent = value; get => P.IsPlatformStateConsistent; }
		[Parameter] public System.Boolean IsPlatformEnabled { set => P.IsPlatformEnabled = value; get => P.IsPlatformEnabled; }
		[Parameter] public Microsoft.Maui.Controls.ResourceDictionary Resources { set => P.Resources = value; get => P.Resources; }
		[Parameter] public Microsoft.Maui.Controls.Style Style { set => P.Style = value; get => P.Style; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindStyle { set { P.SetBinding(Microsoft.Maui.Controls.Button.StyleProperty, value); } }
		[Parameter] public System.Collections.Generic.IList<System.String> StyleClass { set => P.StyleClass = value; get => P.StyleClass; }
		[Parameter] public System.Collections.Generic.IList<System.String> @class { set => P.@class = value; get => P.@class; }
		[Parameter] public System.String AutomationId { set => P.AutomationId = value; get => P.AutomationId; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindAutomationId { set { P.SetBinding(Microsoft.Maui.Controls.Button.AutomationIdProperty, value); } }
		[Parameter] public System.String ClassId { set => P.ClassId = value; get => P.ClassId; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindClassId { set { P.SetBinding(Microsoft.Maui.Controls.Button.ClassIdProperty, value); } }
		[Parameter] public System.String StyleId { set => P.StyleId = value; get => P.StyleId; }
		[Parameter] public Microsoft.Maui.Controls.Element Parent { set => P.Parent = value; get => P.Parent; }
		[Parameter] public Microsoft.Maui.Controls.IEffectControlProvider EffectControlProvider { set => P.EffectControlProvider = value; get => P.EffectControlProvider; }
		[Parameter] public System.Object BindingContext { set => P.BindingContext = value; get => P.BindingContext; }
		[Parameter] public Microsoft.Maui.Controls.Binding BindBindingContext { set { P.SetBinding(Microsoft.Maui.Controls.Button.BindingContextProperty, value); } }
        public override Task SetParametersAsync(ParameterView parameters)
        {
            foreach (var parameter in parameters)
            {
                switch (parameter.Name)
                {
                    case nameof(Clicked):
                    	Clicked = (System.EventHandler)parameter.Value;
                    break;
                    case nameof(OnClicked):
                    	OnClicked = (EventCallback)parameter.Value;
                    break;
                    case nameof(Pressed):
                    	Pressed = (System.EventHandler)parameter.Value;
                    break;
                    case nameof(OnPressed):
                    	OnPressed = (EventCallback)parameter.Value;
                    break;
                    case nameof(Released):
                    	Released = (System.EventHandler)parameter.Value;
                    break;
                    case nameof(OnReleased):
                    	OnReleased = (EventCallback)parameter.Value;
                    break;
                    case nameof(ChildrenReordered):
                    	ChildrenReordered = (System.EventHandler)parameter.Value;
                    break;
                    case nameof(OnChildrenReordered):
                    	OnChildrenReordered = (EventCallback)parameter.Value;
                    break;
                    case nameof(Focused):
                    	Focused = (System.EventHandler<Microsoft.Maui.Controls.FocusEventArgs>)parameter.Value;
                    break;
                    case nameof(OnFocused):
                    	OnFocused = (EventCallback<Microsoft.Maui.Controls.FocusEventArgs>)parameter.Value;
                    break;
                    case nameof(MeasureInvalidated):
                    	MeasureInvalidated = (System.EventHandler)parameter.Value;
                    break;
                    case nameof(OnMeasureInvalidated):
                    	OnMeasureInvalidated = (EventCallback)parameter.Value;
                    break;
                    case nameof(SizeChanged):
                    	SizeChanged = (System.EventHandler)parameter.Value;
                    break;
                    case nameof(OnSizeChanged):
                    	OnSizeChanged = (EventCallback)parameter.Value;
                    break;
                    case nameof(Unfocused):
                    	Unfocused = (System.EventHandler<Microsoft.Maui.Controls.FocusEventArgs>)parameter.Value;
                    break;
                    case nameof(OnUnfocused):
                    	OnUnfocused = (EventCallback<Microsoft.Maui.Controls.FocusEventArgs>)parameter.Value;
                    break;
                    case nameof(BatchCommitted):
                    	BatchCommitted = (System.EventHandler<Microsoft.Maui.Controls.Internals.EventArg<Microsoft.Maui.Controls.VisualElement>>)parameter.Value;
                    break;
                    case nameof(OnBatchCommitted):
                    	OnBatchCommitted = (EventCallback<Microsoft.Maui.Controls.Internals.EventArg<Microsoft.Maui.Controls.VisualElement>>)parameter.Value;
                    break;
                    case nameof(FocusChangeRequested):
                    	FocusChangeRequested = (System.EventHandler<Microsoft.Maui.Controls.VisualElement.FocusRequestArgs>)parameter.Value;
                    break;
                    case nameof(OnFocusChangeRequested):
                    	OnFocusChangeRequested = (EventCallback<Microsoft.Maui.Controls.VisualElement.FocusRequestArgs>)parameter.Value;
                    break;
                    case nameof(Loaded):
                    	Loaded = (System.EventHandler)parameter.Value;
                    break;
                    case nameof(OnLoaded):
                    	OnLoaded = (EventCallback)parameter.Value;
                    break;
                    case nameof(Unloaded):
                    	Unloaded = (System.EventHandler)parameter.Value;
                    break;
                    case nameof(OnUnloaded):
                    	OnUnloaded = (EventCallback)parameter.Value;
                    break;
                    case nameof(ChildAdded):
                    	ChildAdded = (System.EventHandler<Microsoft.Maui.Controls.ElementEventArgs>)parameter.Value;
                    break;
                    case nameof(OnChildAdded):
                    	OnChildAdded = (EventCallback<Microsoft.Maui.Controls.ElementEventArgs>)parameter.Value;
                    break;
                    case nameof(ChildRemoved):
                    	ChildRemoved = (System.EventHandler<Microsoft.Maui.Controls.ElementEventArgs>)parameter.Value;
                    break;
                    case nameof(OnChildRemoved):
                    	OnChildRemoved = (EventCallback<Microsoft.Maui.Controls.ElementEventArgs>)parameter.Value;
                    break;
                    case nameof(DescendantAdded):
                    	DescendantAdded = (System.EventHandler<Microsoft.Maui.Controls.ElementEventArgs>)parameter.Value;
                    break;
                    case nameof(OnDescendantAdded):
                    	OnDescendantAdded = (EventCallback<Microsoft.Maui.Controls.ElementEventArgs>)parameter.Value;
                    break;
                    case nameof(DescendantRemoved):
                    	DescendantRemoved = (System.EventHandler<Microsoft.Maui.Controls.ElementEventArgs>)parameter.Value;
                    break;
                    case nameof(OnDescendantRemoved):
                    	OnDescendantRemoved = (EventCallback<Microsoft.Maui.Controls.ElementEventArgs>)parameter.Value;
                    break;
                    case nameof(ParentChanging):
                    	ParentChanging = (System.EventHandler<Microsoft.Maui.Controls.ParentChangingEventArgs>)parameter.Value;
                    break;
                    case nameof(OnParentChanging):
                    	OnParentChanging = (EventCallback<Microsoft.Maui.Controls.ParentChangingEventArgs>)parameter.Value;
                    break;
                    case nameof(ParentChanged):
                    	ParentChanged = (System.EventHandler)parameter.Value;
                    break;
                    case nameof(OnParentChanged):
                    	OnParentChanged = (EventCallback)parameter.Value;
                    break;
                    case nameof(HandlerChanging):
                    	HandlerChanging = (System.EventHandler<Microsoft.Maui.Controls.HandlerChangingEventArgs>)parameter.Value;
                    break;
                    case nameof(OnHandlerChanging):
                    	OnHandlerChanging = (EventCallback<Microsoft.Maui.Controls.HandlerChangingEventArgs>)parameter.Value;
                    break;
                    case nameof(HandlerChanged):
                    	HandlerChanged = (System.EventHandler)parameter.Value;
                    break;
                    case nameof(OnHandlerChanged):
                    	OnHandlerChanged = (EventCallback)parameter.Value;
                    break;
                    case nameof(BindingContextChanged):
                    	BindingContextChanged = (System.EventHandler)parameter.Value;
                    break;
                    case nameof(OnBindingContextChanged):
                    	OnBindingContextChanged = (EventCallback)parameter.Value;
                    break;
                    case nameof(Padding):
                    	Padding = (Microsoft.Maui.Thickness)parameter.Value;
                    break;
                    case nameof(BindPadding):
                    	BindPadding = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(LineBreakMode):
                    	LineBreakMode = (Microsoft.Maui.LineBreakMode)parameter.Value;
                    break;
                    case nameof(BindLineBreakMode):
                    	BindLineBreakMode = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(BorderColor):
                    	BorderColor = (Microsoft.Maui.Graphics.Color)parameter.Value;
                    break;
                    case nameof(BindBorderColor):
                    	BindBorderColor = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(CornerRadius):
                    	CornerRadius = (System.Int32)parameter.Value;
                    break;
                    case nameof(BindCornerRadius):
                    	BindCornerRadius = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(BorderWidth):
                    	BorderWidth = (System.Double)parameter.Value;
                    break;
                    case nameof(BindBorderWidth):
                    	BindBorderWidth = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(ContentLayout):
                    	ContentLayout = (Microsoft.Maui.Controls.Button.ButtonContentLayout)parameter.Value;
                    break;
                    case nameof(BindContentLayout):
                    	BindContentLayout = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(Command):
                    	Command = (System.Windows.Input.ICommand)parameter.Value;
                    break;
                    case nameof(BindCommand):
                    	BindCommand = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(OnCommand):
                    	OnCommand = (EventCallback)parameter.Value;
                    break;
                    case nameof(CommandParameter):
                    	CommandParameter = (System.Object)parameter.Value;
                    break;
                    case nameof(BindCommandParameter):
                    	BindCommandParameter = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(ImageSource):
                    	ImageSource = (Microsoft.Maui.Controls.ImageSource)parameter.Value;
                    break;
                    case nameof(BindImageSource):
                    	BindImageSource = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(Text):
                    	Text = (System.String)parameter.Value;
                    break;
                    case nameof(BindText):
                    	BindText = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(TextColor):
                    	TextColor = (Microsoft.Maui.Graphics.Color)parameter.Value;
                    break;
                    case nameof(BindTextColor):
                    	BindTextColor = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(CharacterSpacing):
                    	CharacterSpacing = (System.Double)parameter.Value;
                    break;
                    case nameof(BindCharacterSpacing):
                    	BindCharacterSpacing = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(FontAttributes):
                    	FontAttributes = (Microsoft.Maui.Controls.FontAttributes)parameter.Value;
                    break;
                    case nameof(BindFontAttributes):
                    	BindFontAttributes = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(FontFamily):
                    	FontFamily = (System.String)parameter.Value;
                    break;
                    case nameof(BindFontFamily):
                    	BindFontFamily = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(FontSize):
                    	FontSize = (System.Double)parameter.Value;
                    break;
                    case nameof(BindFontSize):
                    	BindFontSize = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(FontAutoScalingEnabled):
                    	FontAutoScalingEnabled = (System.Boolean)parameter.Value;
                    break;
                    case nameof(BindFontAutoScalingEnabled):
                    	BindFontAutoScalingEnabled = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(TextTransform):
                    	TextTransform = (Microsoft.Maui.TextTransform)parameter.Value;
                    break;
                    case nameof(BindTextTransform):
                    	BindTextTransform = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(HorizontalOptions):
                    	HorizontalOptions = (Microsoft.Maui.Controls.LayoutOptions)parameter.Value;
                    break;
                    case nameof(BindHorizontalOptions):
                    	BindHorizontalOptions = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(Margin):
                    	Margin = (Microsoft.Maui.Thickness)parameter.Value;
                    break;
                    case nameof(BindMargin):
                    	BindMargin = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(VerticalOptions):
                    	VerticalOptions = (Microsoft.Maui.Controls.LayoutOptions)parameter.Value;
                    break;
                    case nameof(BindVerticalOptions):
                    	BindVerticalOptions = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(Frame):
                    	Frame = (Microsoft.Maui.Graphics.Rect)parameter.Value;
                    break;
                    case nameof(Handler):
                    	Handler = (Microsoft.Maui.IViewHandler)parameter.Value;
                    break;
                    case nameof(Shadow):
                    	Shadow = (Microsoft.Maui.Controls.Shadow)parameter.Value;
                    break;
                    case nameof(BindShadow):
                    	BindShadow = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(ZIndex):
                    	ZIndex = (System.Int32)parameter.Value;
                    break;
                    case nameof(Visual):
                    	Visual = (Microsoft.Maui.Controls.IVisual)parameter.Value;
                    break;
                    case nameof(BindVisual):
                    	BindVisual = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(FlowDirection):
                    	FlowDirection = (Microsoft.Maui.FlowDirection)parameter.Value;
                    break;
                    case nameof(BindFlowDirection):
                    	BindFlowDirection = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(AnchorX):
                    	AnchorX = (System.Double)parameter.Value;
                    break;
                    case nameof(BindAnchorX):
                    	BindAnchorX = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(AnchorY):
                    	AnchorY = (System.Double)parameter.Value;
                    break;
                    case nameof(BindAnchorY):
                    	BindAnchorY = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(BackgroundColor):
                    	BackgroundColor = (Microsoft.Maui.Graphics.Color)parameter.Value;
                    break;
                    case nameof(BindBackgroundColor):
                    	BindBackgroundColor = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(Background):
                    	Background = (Microsoft.Maui.Controls.Brush)parameter.Value;
                    break;
                    case nameof(BindBackground):
                    	BindBackground = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(HeightRequest):
                    	HeightRequest = (System.Double)parameter.Value;
                    break;
                    case nameof(BindHeightRequest):
                    	BindHeightRequest = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(InputTransparent):
                    	InputTransparent = (System.Boolean)parameter.Value;
                    break;
                    case nameof(BindInputTransparent):
                    	BindInputTransparent = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(IsEnabled):
                    	IsEnabled = (System.Boolean)parameter.Value;
                    break;
                    case nameof(BindIsEnabled):
                    	BindIsEnabled = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(IsVisible):
                    	IsVisible = (System.Boolean)parameter.Value;
                    break;
                    case nameof(BindIsVisible):
                    	BindIsVisible = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(MinimumHeightRequest):
                    	MinimumHeightRequest = (System.Double)parameter.Value;
                    break;
                    case nameof(BindMinimumHeightRequest):
                    	BindMinimumHeightRequest = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(MinimumWidthRequest):
                    	MinimumWidthRequest = (System.Double)parameter.Value;
                    break;
                    case nameof(BindMinimumWidthRequest):
                    	BindMinimumWidthRequest = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(MaximumHeightRequest):
                    	MaximumHeightRequest = (System.Double)parameter.Value;
                    break;
                    case nameof(BindMaximumHeightRequest):
                    	BindMaximumHeightRequest = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(MaximumWidthRequest):
                    	MaximumWidthRequest = (System.Double)parameter.Value;
                    break;
                    case nameof(BindMaximumWidthRequest):
                    	BindMaximumWidthRequest = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(Opacity):
                    	Opacity = (System.Double)parameter.Value;
                    break;
                    case nameof(BindOpacity):
                    	BindOpacity = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(Rotation):
                    	Rotation = (System.Double)parameter.Value;
                    break;
                    case nameof(BindRotation):
                    	BindRotation = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(RotationX):
                    	RotationX = (System.Double)parameter.Value;
                    break;
                    case nameof(BindRotationX):
                    	BindRotationX = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(RotationY):
                    	RotationY = (System.Double)parameter.Value;
                    break;
                    case nameof(BindRotationY):
                    	BindRotationY = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(Scale):
                    	Scale = (System.Double)parameter.Value;
                    break;
                    case nameof(BindScale):
                    	BindScale = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(ScaleX):
                    	ScaleX = (System.Double)parameter.Value;
                    break;
                    case nameof(BindScaleX):
                    	BindScaleX = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(ScaleY):
                    	ScaleY = (System.Double)parameter.Value;
                    break;
                    case nameof(BindScaleY):
                    	BindScaleY = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(TranslationX):
                    	TranslationX = (System.Double)parameter.Value;
                    break;
                    case nameof(BindTranslationX):
                    	BindTranslationX = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(TranslationY):
                    	TranslationY = (System.Double)parameter.Value;
                    break;
                    case nameof(BindTranslationY):
                    	BindTranslationY = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(WidthRequest):
                    	WidthRequest = (System.Double)parameter.Value;
                    break;
                    case nameof(BindWidthRequest):
                    	BindWidthRequest = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(Clip):
                    	Clip = (Microsoft.Maui.Controls.Shapes.Geometry)parameter.Value;
                    break;
                    case nameof(BindClip):
                    	BindClip = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(DisableLayout):
                    	DisableLayout = (System.Boolean)parameter.Value;
                    break;
                    case nameof(IsInPlatformLayout):
                    	IsInPlatformLayout = (System.Boolean)parameter.Value;
                    break;
                    case nameof(IsPlatformStateConsistent):
                    	IsPlatformStateConsistent = (System.Boolean)parameter.Value;
                    break;
                    case nameof(IsPlatformEnabled):
                    	IsPlatformEnabled = (System.Boolean)parameter.Value;
                    break;
                    case nameof(Resources):
                    	Resources = (Microsoft.Maui.Controls.ResourceDictionary)parameter.Value;
                    break;
                    case nameof(Style):
                    	Style = (Microsoft.Maui.Controls.Style)parameter.Value;
                    break;
                    case nameof(BindStyle):
                    	BindStyle = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(StyleClass):
                    	StyleClass = (System.Collections.Generic.IList<System.String>)parameter.Value;
                    break;
                    case nameof(@class):
                    	@class = (System.Collections.Generic.IList<System.String>)parameter.Value;
                    break;
                    case nameof(AutomationId):
                    	AutomationId = (System.String)parameter.Value;
                    break;
                    case nameof(BindAutomationId):
                    	BindAutomationId = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(ClassId):
                    	ClassId = (System.String)parameter.Value;
                    break;
                    case nameof(BindClassId):
                    	BindClassId = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                    case nameof(StyleId):
                    	StyleId = (System.String)parameter.Value;
                    break;
                    case nameof(Parent):
                    	Parent = (Microsoft.Maui.Controls.Element)parameter.Value;
                    break;
                    case nameof(EffectControlProvider):
                    	EffectControlProvider = (Microsoft.Maui.Controls.IEffectControlProvider)parameter.Value;
                    break;
                    case nameof(BindingContext):
                    	BindingContext = (System.Object)parameter.Value;
                    break;
                    case nameof(BindBindingContext):
                    	BindBindingContext = (Microsoft.Maui.Controls.Binding)parameter.Value;
                    break;
                }
            }
            return base.SetParametersAsync(parameters);
        }

    }

This works rather well for us and I am thinking perhaps merging this into this library. Let me know your thoughts

[Q] Attached props

Hi. i like this project and waiting for official support too.

Whats your thoughts about attached properties? How to impliment em?
It seems attached props will require changes in Blazor itself

Update Picker.ItemDisplayBinding to be Func instead of string

Currently in our Picker implementation ItemDisplayBinding property has a string type, which represents property name which should be displayed, so if I have the following item type:

class Item
{
	public string Id {get;set;}
	public string Name {get;set;}
}

I can use ItemDisplayBinding="Name" so Picker would use this property for items.

But
a) It has no compile time validation
b) It's not flexible. What if I want to use multiple properties for display item or use custom function?

It should be Func instead (ItemDisplayBinding="i => i.Name").
We can use Maui's TypedBinding to convert Func to Binding to be able to assign it to Maui's control.

One thing I'm not sure about is naming. Does it make sense to rename it to smth like ItemDisplaySelector? Since it has no relation to Maui's Bindings? Or leave it as is?

CollectionView issues

  • Grouping is not supported
    Because CollectionView is a generic component, it is not possible to set ItemsSource to some Groupping type. I suppose I could simply define a separate property (e.g. GrouppedItemsSource) for this purpose.

  • ItemsSource should be an ObservableCollection if you need to handle items addition/removal.
    We need that since items are managed outside of Blazor. That's not really a Blazor way though.
    Maybe it's possible to use some kind of wrapper, and calculate diffs between updates, not sure.

  • SelectedItems property has object type.
    I cannot simply cast IList<object> to IList<T>. And I cannot simply invoke .Cast<T>().ToList(), because that leads to an infinite loop if property is binded.

  • SelectedItem property has object type.
    Slightly different issue here. T can be both class and struct. OTOH, SelectedItem is nullable. I don't know how to declare a nullable type which would work in generic context without constraints.

  • Templated Header/Footer/Empty view are not supported.
    Decided to implement separately.

  • Because added items are rendered asynchronously, sequence of actions is not always obvious.
    In my case, I'm adding items to the source, and removing the activity indicator from footer when items are loaded (infinite scroll).
    But from XF perspective it happens the opposite way - activity indicator is removed, and then items are added. This leads to slightly wrong scroll position.
    I was able to workaround that by adding await Task.Yield() to the end of my method.
    Not sure how to resolve it globally.

How to use FlyoutPage instead of Shell

Hi
I want to use FlyoutPage instead of Shell, but when I replaced Shell in AppShell.razor with FlyoutPage it shows blank page
AppShell.razor:

<FlyoutPage Title="Flyout">
    <Flyout>
        <ContentPage Title="Menu">
            <StackLayout>
                <Button Text="Page 1" />
                <Button Text="Page 2" />
            </StackLayout>
        </ContentPage>
    </Flyout>
    <Detail>
        <MainPage />
    </Detail>
</FlyoutPage>

App.cs:

using BlazorBindings.Maui;
namespace App1
{
    public partial class App : Application
    {
        public App(MauiBlazorBindingsRenderer renderer)
        {
            renderer.AddComponent<AppShell>(this);
        }
    }
}

Rework approach with handlers

Our current approach with elements and handlers is not the easiest one. We set properties to control component, which renders all of them to render tree. Renderer picks up corresponding handler, which handles parameters, and sets them to Maui control type.

I suggest to merge those types together. Set parameters to Maui control type directly in component's SetParametersAsync method. We still need to render RenderFragment properties to the RenderTree (e.g. ChildContent).

How to use style in BlazorBindings

I cannot find an example about CSS style. Can you provide an example to use CSS style?
Is it possible to use XAML style in Resources/Styles/Styles.xaml? If not, how can we translate it to CSS?

If I add a css like below, I got an exception.

<StyleSheet Resource="mystyle.css" Assembly="GetType().Assembly"></StyleSheet>
<TabbedPage>

    <ContentPage Title="Todo">
        <StackLayout>
            <Label FontSize="20" TextColor="Colors.Crimson" Text="Todo Items" HorizontalTextAlignment="TextAlignment.Center" />
            <TodoList />
        </StackLayout>
    </ContentPage>

    <ContentPage Title="Counter">
        <Counter />
    </ContentPage>

    <ContentPage Title="About">
        <About />
    </ContentPage>

</TabbedPage>

It cannot work and I found this exception.

System.ArgumentException: 'parentElement (Parameter 'Expected parent to be of type 'Microsoft.Maui.Controls.VisualElement' but it is of type 'BlazorBindings.Maui.BlazorBindingsApplication`1[[BlazorBindingsToDo.TodoApp, BlazorBindingsToDo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'.')'

Add support for RadioButton

Expected syntax:

            <RadioButtonGroup @bind-SelectedValue="selectedValue">
                <RadioButton Value="A" />
                <RadioButton Value="B" />
                <RadioButton Value="C" />
            </RadioButtonGroup>

@code {
     string selectedValue;
}

Allow to replace the whole navigation stack during the navigation

At the outset, would like to appreciate the effort that's being made to make this AppModel alive by adding features to it.

And while trying the preview NuGet package (0.9.2-preview), came across this issue.

This is being generic Shell definition used across many projects with both Flyout items and Tab (meant to be hidden from the flyout menu and invoked on demand like the Login page).

But when such is definition is used with this Blazor Bindings model, navigating to the Tab defined page opens up with the Flyout menu still open and that page is pushed onto the Navigation stack as a back button is still present. Need a way to define Attached Properties to make this a Modal page.

And the next part of the issue is while moving from the Tab page to any other page, behaves like a usual regular Navigation page. pushed onto the stack. The intended behavior is to replace the entire Navigation stack and start afresh.

This feature needs to be added in this AppModel on how to start navigation afresh (maybe with additional parameters to the NavigateToAsync method as the underlying Native Shell implementation does support that feature with route address ///home).

Screenshots:

Tab page with Flyout menu still open:

maui-blazor-bindings-tab-page-open-flyout

Tab page with back button:

maui-blazor-bindings-tab-page-back-button

URI navigation improvements

  • Proper support for path parameters (#117)
  • Support navigating to the page already present in the Shell
  • RootWrapper / ErrorBoundary support (#115)
  • Support navigation upwards from the current position
  • Support replacing the navigation stack
  • Support Shell.PresentationMode

Add the ability to perform non-Shell page navigation

Currently we have ShellNavigationManager for url-based navigation, but it has its own limitations:

  • Can be used with Shell only
  • Cannot pass arbitrary parameters, only the ones based on URL
  • Cannot be used with modals (we have ModalContainer for modals, but it's not very convenient)

I would suggest to add a service for navigation, which would allow to work with components:

interface INavigationService
{
    Task PushAsync<T>(Dictionary<string, object> arguments = null, bool animated = true) where T: IComponent;
    Task PushModalAsync<T>(Dictionary<string, object> arguments = null, bool animated = true) where T: IComponent;

    // Optional, just for convenience (as you can do same now via NativeElement property)
    Task PopToRootAsync(bool animated = true);
    Task PopModalAsync(bool animated = true);
    Task PopAsync(bool animated = true);    
}

This way navigation would look smth like that:

       @inject INavigationService NavigationService

	async Task Navigate()
	{
		await NavigationService.PushAsync<MyPage>(new()
		{
			[nameof(MyPage.Parameter1)] = arg1,
			[nameof(MyPage.Parameter2)] = arg2
		});
	}

It would be great to design this service with extensibility in mind, so that I could, for example, add extension method ShowPopupAsync to display XCT's Popup.

Open questions:

  • How to name it to avoid confusion? We have ShellNavigationManager, we have NavigationManager from web Blazor, would NavigationService be fine?
  • Would it make any sense to merge it with existing ShellNavigationManager ?
  • Can I always use Application.Current.MainPage.Navigation to get INavigation?
  • Is there any Navigated event we could use to dispose the renderer when the page is closed?

Label element should support text content

Even though this is suggested in our home page
<Label FontSize="30">You pressed @count times </Label>

It is not actually supported, you need to provide Text property instead.

Remove default Error Page

Currently our blazor renderer shows white page with an exception details in case exception is unhandled. That is not Prod-ready at all, and messes with debug experience (debugger doesn't break by default on such exceptions).

This page should be removed, and we should rethrow the exception instead (preserving the stacktrace), and let the platform handle that (or not). If someone really needs that behavior, they can use their own subclass of the renderer.

Is there a way to override OnAppearing()?

We can override content page method OnAppearing() in XAML. Is there a way to do the same in Razor page?

Razor page uses OnInitialized(), OnParametersSetAsync() or OnAfterRenderAsync() etc., but these methods cannot replace OnAppearing(), OnNavigated() etc. content page life cycle methods.


I can create a derived class of content page to override lifecycle methods such as OnAppearing().

    public class ItemListPage : ContentPage
    {
        protected override void OnAppearing()
        {
            base.OnAppearing();
        }
    }

<ItemListPage>
    <RefreshView OnRefreshing="LoadItems" IsRefreshing="IsBusy">
        <ListView ItemsSource="Items">
            <ItemTemplate>
                <ViewCell>
                    <Label>@context.Name</Label>
                    <Label>@context.Description</Label>
                </ViewCell>
            </ItemTemplate>
        </ListView>
    </RefreshView>
</ItemListPage>

It seems this cannot work. It got the below error message.

Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing root component 0 (PassXYZ.Vault.AppShell)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 0 of type PassXYZ.Vault.AppShell
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 1 (BlazorBindings.Maui.Elements.Shell) as child of 0 (PassXYZ.Vault.AppShell)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 1 of type BlazorBindings.Maui.Elements.Shell
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 2 (BlazorBindings.Maui.Elements.TabBar) as child of 1 (BlazorBindings.Maui.Elements.Shell)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 3 (BlazorBindings.Maui.Elements.FlyoutItem) as child of 1 (BlazorBindings.Maui.Elements.Shell)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 4 (BlazorBindings.Maui.Elements.FlyoutItem) as child of 1 (BlazorBindings.Maui.Elements.Shell)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 5 (BlazorBindings.Maui.Elements.MenuItem) as child of 1 (BlazorBindings.Maui.Elements.Shell)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 2 of type BlazorBindings.Maui.Elements.TabBar
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 6 (BlazorBindings.Maui.Elements.ShellContent) as child of 2 (BlazorBindings.Maui.Elements.TabBar)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 3 of type BlazorBindings.Maui.Elements.FlyoutItem
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 7 (BlazorBindings.Maui.Elements.ShellContent) as child of 3 (BlazorBindings.Maui.Elements.FlyoutItem)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 4 of type BlazorBindings.Maui.Elements.FlyoutItem
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 8 (BlazorBindings.Maui.Elements.ShellContent) as child of 4 (BlazorBindings.Maui.Elements.FlyoutItem)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 5 of type BlazorBindings.Maui.Elements.MenuItem
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 6 of type BlazorBindings.Maui.Elements.ShellContent
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 9 (PassXYZ.Vault.Pages.LoginPage) as child of 6 (BlazorBindings.Maui.Elements.ShellContent)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 7 of type BlazorBindings.Maui.Elements.ShellContent
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 10 (PassXYZ.Vault.Pages.AboutPage) as child of 7 (BlazorBindings.Maui.Elements.ShellContent)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 8 of type BlazorBindings.Maui.Elements.ShellContent
Exception thrown: 'System.ArgumentNullException' in Microsoft.Extensions.Logging.Abstractions.dll
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 11 (PassXYZ.Vault.Pages.ItemsPage) as child of 8 (BlazorBindings.Maui.Elements.ShellContent)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 9 of type PassXYZ.Vault.Pages.LoginPage
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 12 (BlazorBindings.Maui.Elements.ContentPage) as child of 9 (PassXYZ.Vault.Pages.LoginPage)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 10 of type PassXYZ.Vault.Pages.AboutPage
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 13 (BlazorBindings.Maui.Elements.ContentPage) as child of 10 (PassXYZ.Vault.Pages.AboutPage)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 11 of type PassXYZ.Vault.Pages.ItemsPage
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 14 (BlazorBindings.Maui.Elements.RefreshView) as child of 11 (PassXYZ.Vault.Pages.ItemsPage)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 15 (BlazorBindings.Maui.Elements.VerticalStackLayout) as child of 11 (PassXYZ.Vault.Pages.ItemsPage)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 12 of type BlazorBindings.Maui.Elements.ContentPage
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 16 (BlazorBindings.Maui.Elements.Internal.ContentPropertyComponent`1[Microsoft.Maui.Controls.ContentPage]) as child of 12 (BlazorBindings.Maui.Elements.ContentPage)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 13 of type BlazorBindings.Maui.Elements.ContentPage
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 17 (BlazorBindings.Maui.Elements.Internal.ContentPropertyComponent`1[Microsoft.Maui.Controls.ContentPage]) as child of 13 (BlazorBindings.Maui.Elements.ContentPage)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 14 of type BlazorBindings.Maui.Elements.RefreshView
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 18 (BlazorBindings.Maui.Elements.Internal.ContentPropertyComponent`1[Microsoft.Maui.Controls.ContentView]) as child of 14 (BlazorBindings.Maui.Elements.RefreshView)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 15 of type BlazorBindings.Maui.Elements.VerticalStackLayout
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 19 (BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView]) as child of 15 (BlazorBindings.Maui.Elements.VerticalStackLayout)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 16 of type BlazorBindings.Maui.Elements.Internal.ContentPropertyComponent`1[Microsoft.Maui.Controls.ContentPage]
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 20 (BlazorBindings.Maui.Elements.VerticalStackLayout) as child of 16 (BlazorBindings.Maui.Elements.Internal.ContentPropertyComponent`1[Microsoft.Maui.Controls.ContentPage])
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 17 of type BlazorBindings.Maui.Elements.Internal.ContentPropertyComponent`1[Microsoft.Maui.Controls.ContentPage]
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 21 (BlazorBindings.Maui.Elements.Grid) as child of 17 (BlazorBindings.Maui.Elements.Internal.ContentPropertyComponent`1[Microsoft.Maui.Controls.ContentPage])
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 18 of type BlazorBindings.Maui.Elements.Internal.ContentPropertyComponent`1[Microsoft.Maui.Controls.ContentView]
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 22 (BlazorBindings.Maui.Elements.ListView`1[PassXYZ.Vault.Models.Item]) as child of 18 (BlazorBindings.Maui.Elements.Internal.ContentPropertyComponent`1[Microsoft.Maui.Controls.ContentView])
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 19 of type BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView]
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 23 (BlazorBindings.Maui.Elements.Button) as child of 19 (BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView])
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 20 of type BlazorBindings.Maui.Elements.VerticalStackLayout
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 24 (BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView]) as child of 20 (BlazorBindings.Maui.Elements.VerticalStackLayout)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 21 of type BlazorBindings.Maui.Elements.Grid
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 25 (BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView]) as child of 21 (BlazorBindings.Maui.Elements.Grid)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 22 of type BlazorBindings.Maui.Elements.ListView`1[PassXYZ.Vault.Models.Item]
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 26 (BlazorBindings.Maui.Elements.DataTemplates.SyncDataTemplateItemsComponent`2[Microsoft.Maui.Controls.ItemsView`1[Microsoft.Maui.Controls.Cell],PassXYZ.Vault.Models.Item]) as child of 22 (BlazorBindings.Maui.Elements.ListView`1[PassXYZ.Vault.Models.Item])
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 23 of type BlazorBindings.Maui.Elements.Button
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 24 of type BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView]
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 27 (BlazorBindings.Maui.Elements.Button) as child of 24 (BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView])
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 25 of type BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView]
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 28 (BlazorBindings.Maui.Elements.GridCell) as child of 25 (BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView])
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 29 (BlazorBindings.Maui.Elements.GridCell) as child of 25 (BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView])
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 26 of type BlazorBindings.Maui.Elements.DataTemplates.SyncDataTemplateItemsComponent`2[Microsoft.Maui.Controls.ItemsView`1[Microsoft.Maui.Controls.Cell],PassXYZ.Vault.Models.Item]
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 27 of type BlazorBindings.Maui.Elements.Button
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 28 of type BlazorBindings.Maui.Elements.GridCell
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 30 (BlazorBindings.Maui.Elements.VerticalStackLayout) as child of 28 (BlazorBindings.Maui.Elements.GridCell)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 29 of type BlazorBindings.Maui.Elements.GridCell
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 31 (BlazorBindings.Maui.Elements.ScrollView) as child of 29 (BlazorBindings.Maui.Elements.GridCell)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 30 of type BlazorBindings.Maui.Elements.VerticalStackLayout
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 32 (BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView]) as child of 30 (BlazorBindings.Maui.Elements.VerticalStackLayout)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 31 of type BlazorBindings.Maui.Elements.ScrollView
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 33 (BlazorBindings.Maui.Elements.Internal.ContentPropertyComponent`1[Microsoft.Maui.Controls.ScrollView]) as child of 31 (BlazorBindings.Maui.Elements.ScrollView)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 32 of type BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView]
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 34 (BlazorBindings.Maui.Elements.Image) as child of 32 (BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView])
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 33 of type BlazorBindings.Maui.Elements.Internal.ContentPropertyComponent`1[Microsoft.Maui.Controls.ScrollView]
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 35 (BlazorBindings.Maui.Elements.VerticalStackLayout) as child of 33 (BlazorBindings.Maui.Elements.Internal.ContentPropertyComponent`1[Microsoft.Maui.Controls.ScrollView])
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 34 of type BlazorBindings.Maui.Elements.Image
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 35 of type BlazorBindings.Maui.Elements.VerticalStackLayout
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 36 (BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView]) as child of 35 (BlazorBindings.Maui.Elements.VerticalStackLayout)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 36 of type BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView]
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 37 (BlazorBindings.Maui.Elements.Label) as child of 36 (BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView])
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 38 (BlazorBindings.Maui.Elements.Label) as child of 36 (BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView])
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 39 (BlazorBindings.Maui.Elements.Label) as child of 36 (BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView])
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 40 (BlazorBindings.Maui.Elements.Button) as child of 36 (BlazorBindings.Maui.Elements.Internal.ListContentPropertyComponent`2[Microsoft.Maui.Controls.Layout,Microsoft.Maui.IView])
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 37 of type BlazorBindings.Maui.Elements.Label
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 38 of type BlazorBindings.Maui.Elements.Label
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 39 of type BlazorBindings.Maui.Elements.Label
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 41 (BlazorBindings.Maui.Elements.Span) as child of 39 (BlazorBindings.Maui.Elements.Label)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Initializing component 42 (BlazorBindings.Maui.Elements.Span) as child of 39 (BlazorBindings.Maui.Elements.Label)
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 40 of type BlazorBindings.Maui.Elements.Button
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 41 of type BlazorBindings.Maui.Elements.Span
Microsoft.AspNetCore.Components.RenderTree.Renderer: Debug: Rendering component 42 of type BlazorBindings.Maui.Elements.Span
Exception thrown: 'System.InvalidOperationException' in System.Private.CoreLib.dll
An exception of type 'System.InvalidOperationException' occurred in System.Private.CoreLib.dll but was not handled in user code
Failed to find ElementHandler for 'ItemListPage'

BindableLayout for FlexLayout?

<FlexLayout Wrap="FlexWrap.Wrap" AlignContent="FlexAlignContent.SpaceEvenly" JustifyContent="FlexJustify.SpaceEvenly"> @foreach (var list in Config.Memes) { foreach (var meme in list) { <VerticalStackLayout Padding="new Thickness(5,5,5,5)" Spacing="5" BackgroundColor="Config.ColorList[RandomNumberGenerator.GetInt32(0, Config.ColorList.Count)]" WidthRequest="100" HeightRequest="100"> <Label Text=@meme TextColor="Config.PageBgColor"/> <Button OnClick="async() => await PlaySoundAsync(meme)" BackgroundColor="Config.Primary" Text="PLAY"/> </VerticalStackLayout> } } </FlexLayout>

Hi,
I'm trying to fit a lot of stacklayouts into a flexlayout and it takes a quite a while to load. Anyway I could use an observable collection with bindable layout?

Rework working with events

Currently we subscribe to every supported event for every rendered element, even if user hasn't added any event handlers. It doesn't help with performance. Moreover, we never unsubscribe from those events, which could potentially lead to memory leaks.

Cannot to get CascadingParam when naviated from INavigation.PushAsync<>()

Cannot to get CascadingParam when naviated from INavigation.PushAsync<>()

public record Theme {
    public string Background { get; init; } = ""#ffffffff";
}

AppShell

<CascadingValue Value="Theme">
    <Shell FlyoutIsPresented="true">
        <ShellContent Title="Navigation">
            <PageNavigatedFrom />
        </ShellContent>
        <ShellContent Title="Navigation">
            <PageNavigatedTo />
        </ShellContent>
    </Shell>
</CascadingValue>

@code {
    Theme Theme { get; } = new();
}

PageNavigateFrom

@inject INavigation Navigation

<ContentPage Padding="12"
             Title="">
    <Button Text="Navigate" OnClick="HandleNavigate" />
</ContentPage>

@code {
    [CascadingParameter]
    Theme? Theme { get; set; }

    void HandleNavigate() {
        Navigation.PushAsync<PageNavigatedTo>();
    }
}

PageNavigateTo

<ContentPage Padding="12"
             Title="">
    <Label Text="@Theme?.Background.ToString()" />
</ContentPage>

@code {
    [CascadingParameter]
    Theme? Theme { get; set; } // Always null
}

DataTemplate known issues

  • It is possible to create DataTemplate from RenderFragment only, and it requires a BindingContext to be set.
    I plan to add support for RenderFragment (non-generic), which doesn't require BindingContext later.

  • Null items are not supported at this point.
    As I mentioned, I decided not to support nulls at this point. I did that to avoid unnecessary updates (CollectionView sets BindingContext to null before changing it to other value for some reason), and because I wanted to avoid the requirement to handle nulls in RenderFragment even when all items provided are not null.

  • Every element created via MbbDataTemplate has an additional ContentView parent. Sometimes that's OK, but probably not always.
    Have no idea how to avoid that.

  • Can't use this approach for ShellContent.ContentTemplate.
    That's a specific case of the previous item. In this case created element should be Page element. But in our case it is wrapped in ContentView, which doesn't work here.
    Maybe it would be possible to handle this properly in different way, not sure.

Consider making Entry generic

Currently Entry has string property Value. It makes it hard to use for numeric types, like decimal, int, double, etc.

Probably it would make sense to make it generic, and add parsing inside of component.

Alternative approach to attached properties using CaptureUnmatchedValues

Since Blazor does not support attached properties natively (see dotnet/aspnetcore#20715, dotnet/aspnetcore#5607, dotnet/aspnetcore#22316), we have to emulate them somehow.
Currently we use the approach with separate Blazor components - either parent (e.g. GridCell) or child (e.g. ShellProperties). However, sometimes it is quite cumbersome and doesn't feel natural.

I have an alternative suggestion.

Create some AttachedPropertyRegistry class, which would allow to register actions for certain attached properties, and register them in corresponding element's static constructor. E.g. for Grid it would look smth like that:

            AttachedPropertyRegistry.RegisterAttachedPropertyHandler("Grid.Row",
                (element, value) => GridLayout.SetRow(element, Convert.ToInt32(value, CultureInfo.InvariantCulture)));

Add property to Element, which would capture all unmatched values:

        [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object> AdditionalProperties { get; set; }

And in ElementHandler try to retrieve and execute action from AttachedPropertyRegistry for all unmatched values.

This approach would allow to use syntax, very close to what is used in XAML:

<Grid ColumnDefinitions="*,*,*" RowDefinitions="*,*,*">
	<Label Grid.Row="0" Grid.Column="0" Text="1" />
	<Label Grid.Row="1" Grid.Column="1" Text="2" />
	<Label Grid.Row="2" Grid.Column="2" Text="3" />
</Grid>

Of course, this approach is not perfect either.
Because this property is a simple Dictionary, there would be no IntelliSense suggestions or compile time validations.
Besides, we probably won't be able to handle complex properties this way, like

<ContentPage ...>    
    <Shell.BackButtonBehavior>
        <BackButtonBehavior Command="{Binding BackCommand}"
                            IconOverride="back.png" />   
    </Shell.BackButtonBehavior>
    ...
</ContentPage>

Error on adding component to an element

Hi
This line of code throws an exception

[Inject]
private MauiBlazorBindingsRenderer Renderer { get; set; }

    protected override async void OnAfterRender(bool firstRender)
    {
        if (firstRender is true)
        {
            ContentPage page = new() { Title = "Ref" };
            await Renderer.AddComponent<MainPage>(page); //Error here
        }
    }

Exception is
image

MainPage is a ContentView
I tried to make it a ContentPage but it throws the same error
I tried this on windows & android

Add default BlazorBindings App class

When used with BlazorBindings, in most cases App class looks like this:

    public class App : Application
    {
        public App(MauiBlazorBindingsRenderer renderer)
        {
            renderer.AddComponent<AppShell>(this);
        }
    }

It is not advised to interact with MauiBlazorBindingsRenderer in user's code, therefore we should add BlazorBindingsApp<T> class, which will render T component as a root.

ComponentWrapperGenerator as SourceGenerator

  1. Convert it to Roslyn source generator.
    This tool should be able to run on build, there is probably no need to commit generated files.
    While it is possible to use it as is as MSBuild task, Source Generators have better VS support, and it would be much easier to customize parametrized assemblies support. Besides, ability to use Roslyn's Syntax classes would probably make code cleaner.

  2. Parametrize input
    TypesToGenerate are currently taken from file, but we need to parametrize other things as well (e.g. namespace).
    It can be a json file (C# analyzer additional file in case of Source Generator), probably something like this:

{
	"rootNamespace": "Microsoft.MobileBlazorBindings.Elements",
	"typesToGenerate": [
		"Xamarin.Forms.ActivityIndicator",
		"Xamarin.Forms.BaseMenuItem",
		"etc"
	]
}
  1. Publish as nuget.
    Project name should be adjusted though, e.g. MobileBlazor.Maui.ComponentGenerator

  2. Generate (most) events.
    It's not straightforward, as we need to have event named correspondingly to properties in order them to be bindable, and XF names do not always match (e.g. IsChecked - CheckedChanged). But I still think that it's possible to handle most of those changes (e.g. trim 'Is' when looking for matching property).

  3. Generate ChildContent handling.
    (Based on ContentProperty attribute on element)

Do not update Maui control Parent

We shouldn't mess with Maui's Parent property, as it might lead to issues. If we need to track parent-child relationship, we need to do that on wrapper level.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.