Upgrading from Xamarin.CommunityToolkit.Markup to CommunityToolkit.Maui.Markup
In Xamarin.Forms
, we used Xamarin.CommunityToolkit.Markup
to create our UI using C# (no XAML).
For .NET MAUI, we can continue to create our UIs in C# (No XAML) thanks to CommunityToolkit.Maui.Markup
.
Let's take a look at the key differences between the two libraries, and then we'll learn how to get started!
Typed Bindings
The biggest update in CommunityToolkit.Maui
is the introduction of Typed Bindings.
With Typed Bindings we can directly reference the property in our ViewModel, avoiding using reflection when INotifyPropertyChanged
is called:
new Label()
.Bind(Label.TextProperty,
getter: (MyViewModel vm) => vm.LabelText,
setter: (MyViewModel vm, string text) => vm.LabelText = text);
With Typed Bindings, we can also include a converter inline, eliminating the need to create a separate IValueConverter
:
new Label()
.Bind(Label.TextProperty,
getter: (MyViewModel vm) => vm.LabelText,
setter: (MyViewModel vm, string text) => vm.LabelText = text,
convert: (string textFromViewModel) => textFromViewModel.Trim(),
convertBack: (string textFromView) => textFromView.Trim());
Learn more about the Typed Bindings here: https://learn.microsoft.com/dotnet/communitytoolkit/maui/markup/extensions/bindable-object-extensions#bind
Relative Bindings
While Typed Bindings are great, they do not support Relative Bindings.
To leverage RelativeBindingSource
, we continue to use the "old" binding engine:
new Label()
.Bind(Label.TextProperty,
nameof(MyViewModel.LabelText),
source: new RelativeBindingSource(RelativeBindingSourceMode.FindAncestorBindingContext, typeof(MyViewModel))
Getting Started
Install CommunityToolkit.Maui.Markup
In your .NET MAUI csproj
file, add the following package reference to CommunityToolkit.Maui.Markup
:
<ItemGroup>
<PackageReference Include="CommunityToolkit.Maui.Markup" Version="4.0.0"/>
</ItemGroup>
Install CommunityToolkit.MVVM
I highly recommend also installing the MVVM Community Toolkit. The MVVM Community Toolkit allows us to remove tons of MVVM boiler-plate code, replacing many lines of code with one attribute, like [ObservableProperty]
and [RelayCommand]
.
You can see how I've used the MVVM Toolkit attributes in the sample code of my ViewModel down below.
In your .NET MAUI csproj
file, add the following package reference to CommunityToolkit.Maui.Markup
:
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2"/>
</ItemGroup>
Learn more about the MVVM Community Toolkit here: https://learn.microsoft.com/dotnet/architecture/maui/mvvm-community-toolkit-features
Creating UI in C#
For this example, let's re-write MainPage.xaml
that is included in the template when we create a File -> New
.NET MAUI app using Visual Studio.
class MainPage : ContentPage
{
public MainPage(MainViewModel vm)
{
BindingContext = vm;
Content = new ScrollView
{
Content = new VerticalStackLayout
{
Spacing = 25,
Padding = 30,
Children =
{
new Label()
.Text("Hello World")
.Font(size: 32)
.CenterHorizontal(),
new Label()
.Text("Welcome to .NET MAUI Markup Community Toolkit Sample")
.Font(size: 18)
.CenterHorizontal(),
new Label()
.Font(size: 18, bold: true)
.CenterHorizontal()
.Bind(Label.TextProperty,
static (MainViewModel vm) => vm.ClickCount,
convert: count => $"Current Count: {count}"),
new Button()
.Text("Click Me")
.Font(bold: true)
.CenterHorizontal()
.Bind(Button.CommandProperty,
static (MainViewModel vm) => vm.IncrementClickMeButtonCommand,
mode: BindingMode.OneTime),
new Image()
.Source("dotnet_bot")
.Size(250, 310)
.CenterHorizontal()
}
}
};
}
}
partial class MainViewModel : ObservableObject
{
[ObservableProperty]
int _clickCount = 0;
[RelayCommand]
void IncrementClickMeButton() => ClickCount++;
}
You can find the completed open-source sample here: https://github.com/brminnick/HelloMauiMarkup