VisualStateManager Extensions
Provides a way of manipulating the visual states of Control
with attached property.
Remarks
VisualStateManager.GoToState
is typically used with Control
where you would set <VisualStateManager.VisualStateGroups>
on the root element of the ControlTemplate. Because this class is implemented using the same method, it means that if you are setting StatesProperty
on an element, the VisualStateManager.VisualStateGroups
should not be set on the very same element, but its first child:
<Page utu:VisualStateManagerExtensions.States="{Binding OnboardingState, Mode=OneWay}">
<!-- Wrong -->
<VisualStateManager.VisualStateGroups>...
<!-- Good -->
<Grid>
<VisualStateManager.VisualStateGroups>...
This "first child" is more common known as the template root within the context of a ControlTemplate
where you typically have a top-level Grid
/Border
/Panel with the x:Name that contains "Root".
Attached Properties
Property | Type | Description |
---|---|---|
States |
string |
Sets the visual states of the control.* |
States*: The accepted value can be a space, comma or semi-colon separated list of visual state names. eg:
- "LoggedIn": just a single state
- "LoggedIn, OnMeteredNetwork": two concurrent states from different visual state groups
- "Pressed, Selected, PressedSelected": with a combined state
Usage
<Page ...
xmlns:utu="using:Uno.Toolkit.UI"
utu:VisualStateManagerExtensions.States="{Binding PageState, Mode=OneWay}">
<Grid ColumnDefinitions="Auto,*" RowDefinitions="*,*,*">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PageStates">
<VisualStateGroup.Transitions>
<VisualTransition From="Red" To="Green">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundBorder"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
From="Red" To="Green" Duration="00:00:00.333" />
</Storyboard>
</VisualTransition>
<!-- repeats for every permutation of [Red,Green,Blue] ... -->
</VisualStateGroup.Transitions>
<VisualState x:Name="Red">
<VisualState.Setters>
<Setter Target="BackgroundBorder.Background" Value="Red" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Green">
<VisualState.Setters>
<Setter Target="BackgroundBorder.Background" Value="Green" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Blue">
<VisualState.Setters>
<Setter Target="BackgroundBorder.Background" Value="Blue" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Button Grid.Row="0" Grid.Column="0"
Content="Red"
Command="{Binding ChangePageStateCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Content}"
CornerRadius="0"
HorizontalAlignment="Stretch" />
<Button Grid.Row="0" Grid.Column="1"
Content="Green"
Command="{Binding ChangePageStateCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Content}"
CornerRadius="0"
HorizontalAlignment="Stretch" />
<Button Grid.Row="0" Grid.Column="2"
Content="Blue"
Command="{Binding ChangePageStateCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Content}"
CornerRadius="0"
HorizontalAlignment="Stretch" />
<Border x:Name="BackgroundBorder"
Grid.Row="1" Grid.ColumnSpan="3" />
public class ViewModel : ViewModelBase
{
public string PageState { get => GetProperty<string>(); set => SetProperty(value); }
public ICommand ChangePageStateCommand => new Command(ChangePageState);
public ViewModel()
{
PageState = "Blue";
}
private void ChangePageState(object parameter)
{
if (parameter is string state)
{
PageState = state;
}
}
}