So we have a pretty nice start to our app. We can display some data, but that data is not only hard coded, it’s hard coded in the XAML file. There’s a clear separation of concerns when it comes to data and presentation. We should follow that. In this post we’ll focus on a pattern of programming known as Model View ViewModel or MVVM for short. This is in the family of patterns as Model View Controller (MVC) and Model View Presenter (MVP). More specifically it allows us to create a ViewModel that we then bind to our View to display data. The View doesn’t need to know how or where the data comes from, and the ViewModel doesn’t need to care how the data is displayed.
Let’s start by creating a ViewModel. Create a folder called ViewModels and in it create a class called
MainViewModel.cs. We name it that because it’s the ViewModel for the Main page. Consistency is king here. Always try to keep naming conventions consistent and you’ll be able to maintain your code better in the future.
There used to be a lot of boilerplate code that we’d have to write to make the ViewModel “active”. What do I mean by “active”? Well when a property changes you want to be notified of that change so the view can update. Also when a command on the View is triggered we want a specific method in the ViewModel to fire. Thankfully there is the Community Toolkit for MVVM available that makes all of this easier. As of this writing the version is 8.0.0-preview4. Open Tools –> NuGet Package Manager –> Manage NuGet Packages for Solution… Then in the tab that opens up select Browse and type
CommunityToolkit.Mvvm. If the version is 7.1.2 make sure that the checkbox Include prerelease is checked and install the 8.0 version that comes up. Hopefully it’ll be released software soon, but the preview seems nice and stable for me.
Anyway, back to our new ViewModel. In the class declaration change it to a
public partial class instead of an
internal class. Then inherit from
ObservableObject. This will create some magic for us that I’ll demonstrate in a minute. Next make sure that you add the
using CommunityToolkit.Mvvm.ComponentModel; directive at the top. While we’re cleaning things up a bit, if you put a semi-colon after the namespace Visual Studio 2022 will get rid of the brackets and move the class in one tab space. Just something I do, you might like the namespace in a parenthesis.
The ViewModel is the model for the view. We want the data that is in there to reflect the data that is displayed to the user. The data that we are showing the user is an array of ActionItem. Let’s add an observable collection of ActionItems to the view model (line 11 below).
Then let’s create a GetActionItems function and decorate it as a RelayCommand. You will have to pull in
using CommunityToolkit.Mvvm.Input for this. Then fill out the rest of the method as follows. This will add our fake ActionItems to the observable collection.
A quick note about
[RelayCommand]: This was simply
[ICommand]in previous builds of the Community Toolkit. Why it changed I don’t know. I just know that code that used to use ICommand works with RelayCommand now.
Before we get this running let’s go back to our MainPage.xaml file and remove the CollectionView.ItemsSource and the array it contains. Next, add a new namespace for the view models with
xmlns:viewmodels="clr-namespace:maui_to_do.ViewModels" and add a data type for the whole page with:
x:DataType="viewmodels:MainViewModel" This will tell the page that all the data comes from a MainViewModel type. Your MainPage.xaml should look like this now:
This is pretty boring right now because we don’t have a way to trigger the loading of data. Let’s surround the CollectionView with a Grid. The grid will have two rows. The first row will contain a button to load the data and the second will show the data. Your new MainPage.xaml should look like this now:
In the code behind add a using statement to pull in the ViewModels and then in the MainPage constructor add
BindingContext = new MainViewModel(); After making this change your MainPage.xaml.cs file will look like this:
Run your application. Press the big button to load data and you’ll be presented with almost the same thing we had before.
There are a number of problems with this and we’ll tackle them in future blog posts. For now let me know what you think of this series.