This is part 4 in an ongoing series in which I will build and dissect a non-trivial app. For details, please see the first in this series.
Part 3 ended with a teaser about the Preferences Page. As you’ll remember, we start with the Preference Model class:
namespace ForgetMeNot.Model;
[ObservableObject]
public partial class Preference
{
[ObservableProperty] private string preferencePrompt;
[ObservableProperty] private string preferenceValue;
}
I explained about ObservableProperties, so I won’t review that here. Let’s see how this model class is used. There are two important related classes: Preferences.xaml and PreferencesViewModel.cs
The Preferences View
The view/page starts with a label explaining that you can add as many types of preferences as you like. We start you with a set of preference prompts (e.g., favorite music, favorite books, etc.) but you are not only free to add your own, you are free to modify ours. All the fields, both prompt and value are free form editable fields.
We’ll start with a couple styles
<Style x:Key="PreferenceStyle" TargetType="Entry">
<Setter Property="BackgroundColor" Value="AntiqueWhite" />
<Setter Property="HorizontalOptions" Value="Start" />
<Setter Property="VerticalOptions" Value="Center" />
<Setter Property="FontSize" Value="10" />
<Setter Property="TextColor" Value="Black" />
<Setter Property="VerticalTextAlignment" Value="Center" />
<Setter Property="WidthRequest" Value="400" />
</Style>
This first one should be pretty straightforward if you are a Xamarin.Forms programmer. Our Entries will use this style. The second one may be a bit new, even though VisualStates are now available in XF.
<Style TargetType="Entry">
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="White" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Wheat" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
The short version of this is that the appearance of the entry will change based on the “state” of the entry. If it is in normal state, the background is white, if it is has focus, however, the background is wheat.

The body of the page has a label that explains how the page works, and a button to save your preferences (the button is at both the top and bottom of the page for the user’s convenience). This is all followed by a CollectionView. Let’s focus on that:
<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>
</CollectionView.ItemTemplate>
</CollectionView>
The ItemsSource for the collection view is a property in the ViewModel. The DataTemplate defines that each entry in the ItemsSource collection will be displayed in a pair of Entry fields. The first will use the item’s PreferencePrompt property and the second will use the PreferenceValue property. Again, all of this will be very familiar if you are an XF programmer. In fact, most of what you’ll see in MAUI will be very familiar — .NET MAUI really is the next incarnation of Xamarin.Forms.
The save button invokes the SavePreferencesCommand, which we’ll also see in the ViewModel.
The ViewModel
PreferencesViewModel has an ObservableProperty and RelayCommands so we’ll mark it as an ObservableObject
[ObservableObject]
public partial class PreferencesViewModel
{
[ObservableProperty] private List<Preference> preferences;
public PreferencesViewModel()
{
Preferences = PreferencesService.GetPreferences();
}
[RelayCommand]
private async Task SavePreferencesAsync()
{
PreferencesService.Save(preferences);
}
}
Nothing surprising or new here except the RelayCommand and the contents of the constructor.
The RelayCommand attributes marks SavePreferencesAsync() as the method called by the SavePreferencesCommand command. The naming is by convention and that is how MAUI associates the bound command in the XAML with the implementing method in the ViewModel. Again, a huge reduction in boilerplate code.
The constructor sets Preferences (which as you see is a list of Preference objects) by invoking GetPreferences on the PreferenceService.
GetPreferences will return a list of Preference objects by going to the client API service. For now, I’m just mocking that the easy way:
public static List<Preference> GetPreferences()
{
return GetPreferencesMock();
}
GetPreferencesMock does not use a “real” mocking object, it just spins up a few preferences and returns them in a list.
private static List<Preference> GetPreferencesMock()
{
List<Preference> preferences = new();
Preference preference = new Preference
{
PreferencePrompt = "Shirt size",
PreferenceValue = "XXL"
};
preferences.Add(preference);
preference = new()
{
PreferencePrompt = "Pants size",
PreferenceValue = "40"
};
preferences.Add(preference);
Not elegant, I admit, but it works and it is temporary. Once we have the API we’ll junk the Mock (or comment it out in case we need it for testing later).
We’re using tabs in this app, and when you click on the Preferences tab you go to the Preferences page:

Note that the user can fill in any answer they want in response to the prompt, and they can even edit the prompt!






































Hey there, You’ve performed an excellent job. I will definitely digg it and personally recommend to my friends. I am sure they’ll be benefited from this website.
Currently it seems like WordPress is the best blogging platform available right now. (from what I’ve read) Is that what you are using on your blog?
At this time it seems like BlogEngine is the preferred blogging platform available right now. (from what I’ve read) Is that what you are using on your blog?
May I simply just say what a relief to find someone that actually knows what they’re discussing over the internet. You definitely realize how to bring an issue to light and make it important. More and more people need to look at this and understand this side of the story. I was surprised that you’re not more popular since you definitely possess the gift.
Excellent pieces. Keep posting such kind of info on your site. Im really impressed by your blog.
Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates. I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this. Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.
Hello there, You have done an incredible job. I’ll definitely digg it and individually recommend to my friends. I’m sure they’ll be benefited from this website.
Currently it looks like Expression Engine is the preferred blogging platform available right now. (from what I’ve read) Is that what you’re using on your blog?
May I simply just say what a comfort to discover somebody who really knows what they’re discussing online. You certainly know how to bring an issue to light and make it important. More people really need to look at this and understand this side of your story. I was surprised you are not more popular since you most certainly possess the gift.
Currently it sounds like Expression Engine is the best blogging platform out there right now. (from what I’ve read) Is that what you’re using on your blog?
May I simply just say what a comfort to find somebody that actually understands what they are talking about on the net. You definitely understand how to bring an issue to light and make it important. More people ought to check this out and understand this side of your story. I was surprised you aren’t more popular because you surely possess the gift.
At this time it looks like Drupal is the best blogging platform available right now. (from what I’ve read) Is that what you are using on your blog?
At this time it seems like BlogEngine is the top blogging platform out there right now. (from what I’ve read) Is that what you’re using on your blog?
Hey there, You have done an excellent job. I’ll definitely digg it and individually recommend to my friends. I am sure they’ll be benefited from this site.
Currently it looks like WordPress is the preferred blogging platform available right now. (from what I’ve read) Is that what you’re using on your blog?
Currently it appears like Drupal is the top blogging platform available right now. (from what I’ve read) Is that what you are using on your blog?
Excellent article. Keep posting such kind of information on your site. Im really impressed by your site.
Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates. I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this. Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.
Hi there, You have performed an incredible job. I will definitely digg it and individually suggest to my friends. I am sure they’ll be benefited from this website.
Wow that was odd. I just wrote an very long comment but after I clicked submit my comment didn’t show up. Grrrr… well I’m not writing all that over again. Regardless, just wanted to say great blog!
Can I simply say what a comfort to discover somebody that really understands what they’re talking about over the internet. You definitely know how to bring a problem to light and make it important. More and more people should read this and understand this side of the story. I can’t believe you aren’t more popular since you certainly have the gift.
Hi there, You’ve done an incredible job. I’ll definitely digg it and in my opinion recommend to my friends. I’m confident they’ll be benefited from this website.
Excellent article. Keep posting such kind of info on your page. Im really impressed by it.
Currently it seems like BlogEngine is the preferred blogging platform out there right now. (from what I’ve read) Is that what you are using on your blog?
Right now it appears like Movable Type is the best blogging platform available right now. (from what I’ve read) Is that what you’re using on your blog?
Aw, this was an extremely good post. Finding the time and actual effort to create a very good article… but what can I say… I hesitate a whole lot and never seem to get anything done.
Right now it sounds like Movable Type is the best blogging platform available right now. (from what I’ve read) Is that what you’re using on your blog?
Aw, this was an incredibly good post. Finding the time and actual effort to generate a very good article… but what can I say… I put things off a whole lot and don’t manage to get nearly anything done.
May I just say what a relief to discover someone who truly knows what they are discussing online. You definitely understand how to bring a problem to light and make it important. A lot more people have to check this out and understand this side of the story. I was surprised that you’re not more popular given that you definitely have the gift.
At this time it appears like Expression Engine is the top blogging platform out there right now. (from what I’ve read) Is that what you’re using on your blog?