Maui.Markup

[删除(380066935@qq.com或微信通知)]

CommunityToolkit/Maui.Markup: The .NET MAUI Markup Community Toolkit is a community-created library that contains Fluent C# Extension Methods to easily create your User Interface in C# (github.com)


.NET MAUI Markup Community Toolkit

The .NET MAUI Markup Community Toolkit is a collection of Fluent C# Extension Methods that allows developers to continue architecting their apps using MVVM, Bindings, Resource Dictionaries, etc., without the need for XAML

All features are contributed by you, our amazing .NET community, and maintained by a core set of maintainers.

And – the best part – the features you add to the .NET MAUI Toolkit may one day be included into the official .NET MAUI library! We leverage the Community Toolkits to debut new features and work closely with the .NET MAUI engineering team to nominate features for promotion.

Getting Started

In order to use the .NET MAUI Community Toolkit you need to call the extension method in your MauiProgram.cs file as follows:

using CommunityToolkit.Maui.Markup;

public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    // Initialise the toolkit
 	builder.UseMauiApp<App>().UseMauiCommunityToolkitMarkup();
    // the rest of your logic...
}

Examples

Here are some brief examples showing how common tasks can be achieved through the use of the Markup package.

Bindings

First let's take a look at how a Binding could be defined without the Markup package:

var entry = new Entry();
entry.SetBinding(Entry.TextProperty, new Binding(nameof(ViewModel.RegistrationCode));

Markup allows us to define the binding fluently and therefore chain multiple methods together to reduce the verbosity of our code:

new Entry().Bind(Entry.TextProperty, nameof(ViewModel.RegistrationCode))

For further details on the possible options for the Bind method refer to the BindableObject extensions documentation.

Sizing

First let's take a look at how an Entry could be sized without the Markup package:

var entry = new Entry();
entry.WidthRequest = 200;
entry.HeightRequest = 40;

Markup allows us to define the sizing fluently and therefore chain multiple methods together to reduce the verbosity of our code:

new Entry().Size(200, 40);

For further details on the possible options for the Size method refer to the VisualElement extensions documentation.

In-depth example

The following example shows setting the page content to a new Grid containing a Label and an Entry, in C#:

class SampleContentPage : ContentPage
{
    public SampleContentPage()
    {
        Grid grid = new Grid
        {
            RowDefinitions =
            {
                new RowDefinition { Height = new GridLength(36, GridUnitType.Absolute) }
            },

            ColumnDefinitions =
            {
                new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },
                new ColumnDefinition { Width = new GridLength(2, GridUnitType.Star) }
            }
        }

        Label label = new Label { Text = "Code: " };
        grid.Children.Add(label);
        GridLayout.SetColumn(label, 0);
        GridLayout.SetRow(label, 0);

        Entry entry = new Entry
        {
            Placeholder = "Enter number",
            Keyboard = Keyboard.Numeric,
            BackgroundColor = Colors.AliceBlue,
            TextColor = Colors.Black,
            FontSize = 15,
            HeightRequest = 44,
            Margin = new Thickness(5)
        };
        grid.Children.Add(entry);
        GridLayout.SetColumn(label, 1);
        GridLayout.SetRow(label, 0);
        entry.SetBinding(Entry.TextProperty, new Binding(nameof(ViewModel.RegistrationCode));

        Content = grid;
    }
}

This example creates a Grid object, with child Label and Entry objects. The Label displays text, and the Entry data binds to the RegistrationCode property of the viewmodel. Each child view is set to appear in a specific row in the Grid, and the Entry spans all the columns in the Grid. In addition, the height of the Entry is set, along with its keyboard, colors, the font size of its text, and its Margin. Finally, the Page.Content property is set to the Grid object.

C# Markup enables this code to be re-written using its fluent API:

using static CommunityToolkit.Maui.Markup.GridRowsColumns;

class SampleContentPage : ContentPage
{
    public SampleContentPage()
    {
        Content = new Grid
        {
            RowDefinitions = Rows.Define(
                (Row.TextEntry, 36)),

            ColumnDefinitions = Columns.Define(
                (Column.Description, Star),
                (Column.Input, Stars(2))),

            Children =
            {
                new Label()
                    .Text("Code:")
                    .Row(Row.TextEntry).Column(Column.Description),

                new Entry
                {
                    Keyboard = Keyboard.Numeric,
                    BackgroundColor = Colors.AliceBlue,
                }.Row(Row.TextEntry).Column(Column.Input)
                 .FontSize(15)
                 .Placeholder("Enter number")
                 .TextColor(Colors.Black)
                 .Height(44)
                 .Margin(5, 5)
                 .Bind(Entry.TextProperty, nameof(ViewModel.RegistrationCode))
            }
        };
    }

    enum Row { TextEntry }
    enum Column { Description, Input }
}

This example is identical to the previous example, but the C# Markup fluent API simplifies the process of building the UI in C#.

C# Markup extensions also allow developers to use an enum to define names for Columns and Rows (e.g. Column.Input).