Tutorial - Settings Screen
Introduction
This document shows how to build a Settings screen using binding. The approach shown here could be used in a code-only project or a project that uses the Gum UI tool to create a screen. It creates a settings screen and a matching view model which stores properties for volume and full screen.
Defining SettingsViewModel
The ViewModel is responsible for storing properties related to the game's settings. A typical game may have dozens of properties for settings, but this example includes a small number to keep the tutorial shorter.
using Gum.Mvvm;
namespace BindingTutorial.ViewModels;
public class SettingsViewModel : ViewModel
{
public float MusicVolume
{
get => Get<float>();
set => Set(value);
}
public float SfxVolume
{
get => Get<float>();
set => Set(value);
}
public bool IsFullScreen
{
get => Get<bool>();
set => Set(value);
}
}Although the view model is a small class, it has a number of details that are worth discussing.
The uses Gum.Mvvm.ViewModel as its base class. This is not a requirement - if you are familiar with an existing framework that offers an INotifyPropertyChanged implementation (such as CommunityToolkit.Mvvm), then you are free to use this with Gum.
Our code above uses the built-in Get and Set methods which are specific to Gum's ViewModel class. These properties provide the following functionality:
Notification of change whenever the Set method is called. This notification is necessary so that UI knows when to update what it is displaying.
Property dependency using the
DependsOnattribute - this is discusses in the Binding Deep Dive page.
If any additional properties need to be added, they should also use Get and Set calls.
Defining SettingsScreen
This section shows how to set up binding in a SettingsScreen class. The binding is the same whether you use the Gum UI tool or a code-only approach.
The SetBinding method is used to associate the view property (such as SfxSlider.Value) with the ViewModel property (such as SettingsViewModel.SfxVolume).
SetBinding takes strings which means it would also be possible to pass the names of the properties. Using the nameof keyword is preferred to this since it reduces the chances of mistakes.
Notice that nameof allows using either an instance to get a property (such as SfxSlider.Value) or a class name (such as SettingsViewModel.SfxVolume). In fact, we could have even replaced SfxSlider.Value with Slider.Value since Value is a property on the Slider class.
Creating a local property for the ViewModel can also help simplify the code slightly. For example, we could modify the code to have a ViewModel property that is used in the SetBinding calls as shown in the following code block:
This approach can also be used to handle events as shown in the Task Screen tutorial.
Using the SettingsScreen
Once the SettingsScreen is defined, we can instantiate it in our game. The following code shows how to create a SettingsScreen instance and assign its BindingContext to a SettingsViewModel instance. Note that we are setting initial values on the view model - these values are shown by our UI when we run the game:
We only needed to set the BindingContext on the SettingsScreen, which is the parent of the other controls. All children inherit the BindingContext of their parent, so we do not need to explicitly assign the BindingContext on each Slider and CheckBox.

Changes to the UI also immediately update the view model. For example, we can modify the ViewModel's SfxVolume to print output whenever it changes.
Any change to the value results in output.

Last updated
Was this helpful?

