Fluent API support #169
Replies: 6 comments 11 replies
-
Issue moved from dotnet/maui#12380
From @Ghostbird on Tuesday, January 3, 2023 7:09:24 AM There is a Fluent API for MAUI. How did you managed to write one yourself without finding that one first? I think they'd welcome your contributions. |
Beta Was this translation helpful? Give feedback.
-
Issue moved from dotnet/maui#12380
From @saint4eva on Tuesday, January 3, 2023 7:40:20 AM
His library feels more natural to me than C# for MarkUp. But both are heavily MVVM oriented. I personally love MVU and that is why I love Comet (C# MVU). But I have been playing around with Sharp.UI library and I am liking it its simplicity - the same as Comet. |
Beta Was this translation helpful? Give feedback.
-
Issue moved from dotnet/maui#12380
From @idexus on Tuesday, January 3, 2023 8:43:19 AM @Ghostbird I got to know this library, unfortunately it doesn't cover all properties in fluid methods because their approach is manual. new Entry()
.Keyboard(Keyboard.Numeric) // <<< compile error in Community Markup
.FontSize(28) I decided to create my lib using source generators. This allowed me to adopt in-line builders, e.g. to create bindings in more intuitive way. new VerticalStackLayout
{
new Slider(1, 100, 1, out var slider),
new Label()
.Text(e => e.Path("Value").StringFormat("Slider Value : {0}"))
.FontSize(e => e.Path("Value"))
.RotationX(e => e.Path("Value")),
} Similarly, it is not possible in Community Markup to do something like this: new ScrollView
{
new Border
{
new Grid
{
new VerticalStackLayout
{
new Label("foo")
.FontSize(30),
new Label("test")
},
new Button()
.Row(1)
.OnClicked(button =>
{
})
}
.RowDefinitions(e => e.Star(3).Star(1))
}
.StrokeShape(new RoundRectangle().CornerRadius(10))
.SizeRequest(200, 300)
}; It can not be done by only extension methods. |
Beta Was this translation helpful? Give feedback.
-
@mattleibow I created an issue but I see that it was redirected here. Personally, I think that to do it right, in an intuitive way, you need to create full support for using MAUI in the code, nowhere else but within the MAUI project. Many of these things can be done with source generators directly in the MAUI project as I have proposed. This cannot be done with extension methods and Community Markup alone. It's just patching holes. |
Beta Was this translation helpful? Give feedback.
-
I do not agree with you. Try to do something like this in the Community Markup without going into "core". public class AlternateCollectionPage : ContentPage
{
class AlternateRowModel
{
public int Id { get; set; }
public object DataModel { get; set; }
public Style LabelStyle => new Style<Label> { Label.TextColorProperty.Set(Id % 2 == 0 ? Colors.DarkSlateGray : Colors.LightGray) };
public Style GridStyle => new Style<Grid> { Grid.BackgroundProperty.Set(Id % 2 == 0 ? Colors.LightGray : Colors.DarkSlateGray) };
}
public AlternateCollectionPage()
{
var itemSource = DataModel.SimpleData
.Select((e, i) => new AlternateRowModel { DataModel = e, Id = i });
Content = new VStack
{
new CollectionView
{
() => new Grid()
{
new Label()
.Text(e => e.Path("DataModel.Name"))
.Style(e => e.Path("LabelStyle"))
}
.Style(e => e.Path("GridStyle"))
}
.ItemsSource(itemSource)
};
}
} |
Beta Was this translation helpful? Give feedback.
-
Hi Everyone! There seems to be 2 main topics here:
First, thank you so much for this Discussion! I'm very excited to see this added to For more information, here's a blog post I wrote when we released the .NET MAUI Community Toolkits: https://devblogs.microsoft.com/dotnet/introducing-the-net-maui-community-toolkit-preview/ Let's pave a path forward here for anyone from the community who would help with this effort!
Edit: This is not possible until partial classes support external assemblies Most .NET MAUI Controls are already using a This means that we can create a second
Edit: This is not possible until partial classes support external assemblies
Edit: This is not possible until partial classes support external assemblies namespace Microsoft.Maui.Controls;
public partial class Button
{
public Button(Thickness padding = default,
LineBreakMode lineBreakMode = default,
Thickness margin = default
// continue adding a parameter for every Property of `Button`, including the properties inherited by `View`
)
{
this.Padding = padding;
this.LineBreakMode = lineBreakMode;
this.Margin = margin;
// continuing assigning every parameter to its Property
}
}
In the After each Proposal has been created, the Community Toolkit core maintainer team will review the Proposal and help refine the details. The team will then vote to Approve the implementation of each Proposal at our monthly standup. After each Proposal has been approved, any community member is welcome to submit a PR implementing it. Extension Methods for .NET MAUI PropertiesBelieve it or not, this is already an existing goal of Implementation
ExampleHere's an existing example from public static TView CenterHorizontal<TView>(this TView view) where TView : View
{
view.HorizontalOptions = LayoutOptions.Center;
return view;
} Next StepsIn the After each Proposal has been created, the Community Toolkit core maintainer team will review the Proposal and help refine the details. The team will then vote to Approve the implementation of each Proposal at our monthly standup. After each Proposal has been approved, any community member is welcome to submit a PR implementing it. |
Beta Was this translation helpful? Give feedback.
-
Issue moved from dotnet/maui#12380
From @idexus on Monday, January 2, 2023 8:09:40 PM
Discussed in dotnet/maui#12273
Description
I would like to have fluent API support in MAUI so first I created a library https://github.com/idexus/Sharp.UI then because some classes are sealed, I decided to create a fork https://github.com/idexus/maui to fully support this feature in the MAUI project. Most code is generated using source generators.
I have two questions
I think for many it would make it much easier to create an interface without the need for XAML, without disabling the possibility of using it.
My goal was:
Unfortunately some classes are sealed, e.g.
PathGeometry
,PathFigure
,TapGestureRecognizer
,PinchGestureRecognizer
,PointerGestureRecognizer
,SwipeGestureRecognizer
,Ellipse
,Polyline
,Line
,Path
,Polygon
,Rectangle
,RoundRectangle
,TableSection
,ColumnDefinition
,RowDefinition
Style
,Trigger
,... etc.If I want to create a library with these classes so that I could create the UI declaratively as I described, only in code using fluent interface, I can't do it without wrapping them.
Detailed description
Below is a description of how each problem was solved.
Properties
Fluent extension methods are generated for all properties and bindable properties (for all derived classes of
BindableObject
, and forStyle
,VisualState
,VisualStateGroup
,VisualStateGroupList
classes)Usage:
Generated methods for
FontSize
property:EventHandler
Fluent extension methods are generated for each
EventHandler
adding anOn
prefixusage example:
generated methods for
Clicked
event handler:ContentProperty
attributesImplementation of
IList
(if not implemented yet) orIEnumerable
interfaces to addAdd()
method support to class are generated for all classes with theContentProperty
attribute.Example usage:
Generated class implementation for single item containers:
Generated class implementation for collection containers:
Constructors
Aditional constructors
Additional constructors have been added to simplify the interface creation process
example usage:
implementation
Additional
out
parameterAdditional constructors with the
out
parameter are generated for all public constructors.usage:
genetated constructor:
In-line value builders
BindingBuilder
For in-line creation of bindings
usage:
ValueBuilder
To set values depending on the app theme, platform or device idiom
LazyValueBuilder
To lazily set values depending on the app theme, platform or device idiom
ColumnDefinitionBuilder
andRowDefinitionBuilder
To define the number and sizes of rows and columns.
example:
In this example you define
Star(2)
,Star()
,Star(3)
Absolute(100)
,Star()
Style
BindableProperty
=>Setter
implementation
IList
Add methodsAdditional
Add()
methods for theIList
interfaceUsage example
User defined classes
[FluentInterface]
attributeFluent methods will be generated for user definied classes with the
[FluentInterface]
attribute[BindableProperties]
attributeBindable properties and fluent methods will be generated for user definied classes with interfaces with the
[BindableProperties]
attributeAdditional atributes:
[DefaultValue]
to define default values[PropertyCallbacks(propertyChanged, propertyChanging,validateValue, coerceValue, defaultValueCreator]
to define callback namesExample
Custom user view example
Beta Was this translation helpful? Give feedback.
All reactions