In the previous postings we looked at creating the basic app and adding a single, simple page. This post will really begin to get into it.
We’re going to have a number of pages
- A page for you to enter your own preferences
- One for looking at your buddy list
- One for look at your buddy’s preferences
- A page for inviting someone to become your buddy
Each of these pages will have its own viewmodel class. We’ll also need services to talk to the API client (e.g., BuddyService with methods to get your buddy list, add to your list, see your buddy’s preferences, etc.)
Finaly, you’ll need model classes to designate what objects will represent the entities in the app. For example, here is the model for a preference object:
[ObservableObject]
public partial class Preference
{
[ObservableProperty] private string preferencePrompt;
[ObservableProperty] private string preferenceValue;
}
There is much to dissect here. First, there are two properties: preferencePrompt and preferenceValue. A prompt might be “Favorite Music Genre” and a value might be “Jazz, HardBop, Classic Rock.” We’ll use a list of these in our preferences page.
But wait! What is with this syntax? The CommunityToolkit.MVVM includes a host of features, but for me one of the most interesting (read coolest) is the set of code generators, which are managed by attributes.
For example, you might previously have written
private string preferencePrompt;
public string PreferencePrompt
{
get => preferencePrompt;
set => SetProperty(ref preferencePrompt, value);
}
But now you can just write
[ObservableProperty] private string preferencePrompt;
This is exactly the same, and you can refer to this property as PreferencePrompt and it will do all the magic for you.
Note that to use ObservableProoperty you will need to mark your class as an ObservableObject as shown above. You will also need a couple using statements,
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
But now, instead of scattering these using statements into each class that needs them, you can create global using statements, that you enter once. I created a file GlobalUsings:
global using CommunityToolkit.Maui;
global using CommunityToolkit.Mvvm.ComponentModel;
global using CommunityToolkit.Mvvm.Input;
global using ForgetMeNot.Helpers;
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading.Tasks;
I can now avoid bringing these into my files, as they are automatically available. Note the keyword global before each, that is the secret sauce.
With the Preference object defined, I can now create a list of these and display them one by one in the Preferences page, as we’ll see in the next posting. As a teaser, here is an excerpt from Preferences.xaml
<CollectionView
Margin="20,20,10,10"
ItemsSource="{Binding Preferences}"
SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid ColumnDefinitions="*,2*">
<Entry
Grid.Column="0"
FontSize="10"
HorizontalOptions="Start"
HorizontalTextAlignment="Start"
Text="{Binding PreferencePrompt, Mode=TwoWay}"
TextColor="{OnPlatform Black, iOS=White}" />
<Entry
Grid.Column="1"
FontSize="10"
HeightRequest="32"
HorizontalOptions="Start"
HorizontalTextAlignment="Start"
Text="{Binding PreferenceValue, Mode=TwoWay}"
TextColor="{OnPlatform Black, iOS=White}"
WidthRequest="350" />
</Grid>
</DataTemplate>
There is much to see here, and we’ll go through it in detail next time, but for now, notice that we have a collection of Preferences serving as the ItemsSource (presumably in the viewmodel) and that the Text for each of our entry controls binds to PreferencePrompt and PreferenceValue respectively.
Can you be more specific about the content of your article? After reading it, I still have some doubts. Hope you can help me.