With the release of my newest book, .NET MAUI For C# Developers, I’m pleased to present occasional posts on advanced topics. If you are just starting out, however, you may want to take a look at my previous 15 part series in which I learn .NET MAUI or my second series that uses the app (Forget Me Not) that we’ll be using here. Finally, you can find my presentations on .NET MAUI and advanced .NET MAUI on YouTube, here.
Managing Visual State
Every VisualElement has a Visual State. For example, does the VisualElement have focus? Is it selected? Xaml allows you to change the presentation of that VisualElement (e.g., a button) based on that state.
The object that sets visual properties on a VisualElement based on its state is the Visual State Manager. The Visual State Manager selects from among a set of VisualStates and displays the view according to styles that you create.
Defining the common visual states
.NET MAUI defines a set of common visual states:
- Normal
- Disabled
- Has focus
- Is selected
- Mouse over (for Windows and MacOs)
.NET MAUI also allows you to define your own visual states.
Button VisualState example
When you first come to the Login page in Forget Me Not, the Submit button is disabled. Once you fill in the two fields of Your Email and Password, the button should turn light green. If you tab to the button it should signify that it has the focus by turning fully green. You can do all this declarative with Visual States.
Visual State and Styles
You can set the visual state on an individual button, or, as we will do here, you can put the visual state XAML into a style and apply it to all the buttons. Here is the complete Style for buttons:
<Style x:Key="LoginButton" TargetType="Button">
<Setter Property="Margin" Value="0,20,0,0" />
<Setter Property="TextColor" Value="Black" />
<Setter Property="WidthRequest" Value="125" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="LightGreen" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Green" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Gray" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
We start by declaring a normal Style, in this case implicit for every button. You may have one or more groups of visual states (we have one). The first group (and in this case the only one) is the CommonStates
We declare each VisualState in turn (here we’re starting with Normal). For each state, we can declare a set of Setters. Our first (and in this case only) Setter sets the BackgroundColor property
We then go on to set the Setters for all the other states. Notice that we did not set the Setter for PointerOver, which means that, on Windows and macOS, if you hover the mouse over the button there will be no change.
.NET MAUI defines specialized visual states for controls. For example, Button adds the Pressed state while CheckBox adds the IsChecked state and CollectionViews adds Selected.
The .NET MAUI community toolkit provides further help for managing the appearance and behavior of your app with a large collection of Behaviors.