XAM320 Design an MVVM ViewModel in Xamarin.Forms

Exercise 1: Driving behavior through properties (XAM320)

In this exercise, you'll add in selection support, and use data triggers to change the UI based on property values exposed in view models.

To complete the exercise, you will need Visual Studio for Windows or macOS with the Xamarin development tools installed. You will also need either an emulator/simulator or a device to run the exercise on. Please see the setup page if you need help installing the Xamarin development environment.

Open the starter solution

Open the starter solution from the Exercise 1 > Start folder in your copy of the cloned or downloaded course materials in either Visual Studio on Windows or Visual Studio for Mac.

Build and run the application to make sure it is working before making changes. It displays quotes using an XML data file as the backing storage. There are two projects that implement the data infrastructure:


Add selection support

Your first step is to add some property support for selection.

  1. Open the MainViewModel and add a new public property of type QuoteViewModel named SelectedQuote. Use a public getter and setter, and use a backing field.
  2. Make sure to implement property change notification when setting the new property - as a quick shortcut, you can use the SetPropertyValue method from the base view model - this will set the underlying field and raise a property change notification for you. It has the form:

    SetPropertyValue<T>(ref T field, T newValue);
    
    QuoteViewModel selectedQuote;
    public QuoteViewModel SelectedQuote {
        get {
            return selectedQuote;
        }
        set {
            SetPropertyValue(ref selectedQuote, value);
        }
    }
    
  3. Next, let's use the property. Open the QuoteListPage.xaml file and locate the ListView. Add a new property binding for the SelectedItem property to the view model property. Use a two-way binding (Mode property). Leave the ItemTapped event handler in place, you still need that for the moment to handle navigation.

    <ListView ItemsSource="{Binding Quotes}"
        SelectedItem="{Binding SelectedQuote, Mode=TwoWay}"
        ItemTapped="OnQuoteSelected">
    
  4. Next, open the code behind file (QuoteListPage.xaml.cs) and locate the OnQuoteSelected method. It's currently passing the tapped item to the QuoteDetailPage as part of the constructor. Remove the parameter, you don't need it anymore as long as the second page has access to the view model!
  5. Finally, open the QuoteDetailPage.xaml.cs file and fix the constructor to not take the parameter. Instead, change the BindingContext to be the SelectedQuote property of the MainViewModel. Remember the view model is a singleton exposed by the App class.
  6. Run the application and make sure it still works properly - it should correctly navigate and still display the quote details when it's on the second screen. However, there is a minor, but annoying bug on some platforms. When you return to the original screen, the ListView still shows selection and the cell you tapped on is highlighted. Let's fix that.
  7. In the QuoteDetailPage constructor, clear the SelectedQuote property (set it to null) after you set the BindingContext. This will clear the ListView selection.
  8. Run the app again to verify the change.

Use DataTriggers

If you examine the QuoteListPage or QuoteDetailPage XAML, you will find it uses a value converter named GenderToColorConverter which is located in the Converters folder. This is located in the application resources and reused on both pages. You're going to remove it from the second page.

  1. Open the QuoteDetailPage XAML file and locate the Label which displays the author name.
  2. Change the TextColor property to just be "Blue" and remove the binding. Now all quote authors will be in blue.
  3. Add a DataTrigger to the Label which changes the TextColor property when the Gender is Gender.Female. Refer to the slides if you need some guidance, or check the code hint below.
  4. Run the application and navigate to the Eleanor Roosevelt quote. The quote author at the bottom of the page should be in pink.
  5. You might want to use the same technique on the QuoteListPage as well - however it won't work there. That's using a TextCell to display the quote - and unfortunately, TextCell does not derive from VisualElement where the trigger support lives. So, it will either need to be changed to a ViewCell with a full Label (which is less efficient than TextCell), or continue using a converter. Here, you've chosen the latter as it doesn't hurt anything, however you could try the former if you have some extra time.
<Label Grid.Row="1" Text="{Binding Author}"
                TextColor="Blue"
                HorizontalOptions="End" HorizontalTextAlignment="End">
    <Label.Triggers>
        <DataTrigger TargetType="Label"
                    Binding="{Binding Gender}"
                    Value="Female">
            <Setter Property="TextColor" Value="Pink" />
        </DataTrigger>
    </Label.Triggers>
</Label>

Exercise summary

In this exercise, you've pushed the selection management into the view model and started removing value converters, instead relying on properties with triggers to control the visual properties.

You can view the completed solution in the Exercise 1 > Completed folder of your copy of the cloned or downloaded course materials.

Go Back