4.1-样式外观:控件状态样式VisualState
控件状态指控件当前处于什么使用状态,如禁用、聚焦、鼠标悬停等等,当控件进入到某种状态时,可以通过【附加属性】【VisualStateManager.VisualStateGroups】设置特定的样式。VisualStateManager.VisualStateGroups的使用结构,套了几层集合,有些复杂,如下图所示:
一、MAUI为可视化控件提供了丰富的内置状态
大多数时候,我们主要通过内置状态来管理控件的状态样式,但如果无法满足开发需求,也可以自定义状态。内置状态包括:
所有派生自VisualElemnet的视觉控件:Normal、Disabled、Focused、PointerOver
- Button和ImageButton特有:Pressed
- CheckBox特有:IsChecked
- RadioButton特有:Checked、Unchecked
- Switch特有:On、Off
- CollectionView特有:Selected
- CarouselView特有:DefaultItem、CurrentItem、PreviousItem、NextItem
二、在控件中定义和使用控件状态样式
<ContentPage
......>
<VerticalStackLayout Padding="10">
<Entry x:Name="entry1" Placeholder="请输入">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<!--正常状态,这个状态必须要有,如果使用默认,可以不设置Setters-->
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<!--聚焦状态-->
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<!--禁用状态-->
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Pink" />
</VisualState.Setters>
</VisualState>
<!--鼠标悬停状态-->
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="LightBlue" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Entry>
<Button Text="禁用/启用输入框" Clicked="Button_Clicked"/>
</VerticalStackLayout>
</ContentPage>
三、在样式中定义和使用控件状态样式
<!--定义隐式样式,自动应用于Entry类型控件-->
<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="Lime" />
</VisualState.Setters>
</VisualState>
......
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
四、在一个控件状态中,影响其它控件的样式
<StackLayout>
<Entry x:Name="entry" Placeholder="请输入" />
<Button Text="点击">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<!--Nomal状态必须要有,如果使用默认样式,则不用设置Setters-->
<VisualState x:Name="Normal" />
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Property="Scale"
Value="0.8" />
<!--设置当前页面entry的Text属性-->
<Setter TargetName="entry"
Property="Entry.Text"
Value="Paris" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Button>
</StackLayout>
五、自定义控件状态及其样式
1、XAML中定义和使用状态样式
<StackLayout x:Name="stackLayout" Padding="10">
<VisualStateManager.VisualStateGroups>
<!--自定义状态组,状态组名称为ValidityStates-->
<VisualStateGroup Name="ValidityStates">
<!--自定义状态Valid,状态名称类型为字符串-->
<VisualState Name="Valid">
<VisualState.Setters>
<!--设置当前页面其它控件的样式-->
<Setter TargetName="label"
Property="Label.TextColor"
Value="Transparent" />
<Setter TargetName="entry"
Property="Entry.BackgroundColor"
Value="Lime" />
</VisualState.Setters>
</VisualState>
<!--自定义状态Invalid-->
<VisualState Name="Invalid">
<!--设置当前页面其它控件的样式-->
<VisualState.Setters>
<Setter TargetName="entry"
Property="Entry.BackgroundColor"
Value="Pink" />
<Setter TargetName="button"
Property="Button.IsEnabled"
Value="False" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Entry x:Name="entry"
Placeholder="555-555-5555"
TextChanged="OnTextChanged" />
<Label x:Name="label"
Text="电话号码格式为555-555-5555, 且不能以0或1开头" />
<Button x:Name="button"
Text="Submit"
FontSize="18"/>
</StackLayout>
2、还需要在后台代码中,通过VisualStateManager.GoToState( 宿主控件,状态值),定义改变控件状态的逻辑
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
//初始化后,调用GoToState函数,设置状态
GoToState(false);
}
//OnTextChanged事件处理程序,使用正则对输入值进行判断。如果符合正则规则,则调用GoToState函数并传入true,反之传入false
void OnTextChanged(object sender, TextChangedEventArgs args)
{
bool isValid = Regex.IsMatch(args.NewTextValue, @"^[2-9]\d{2}-\d{3}-\d{4}$");
GoToState(isValid);
}
//通过GoToState函数设置状态
//根据传入的参数值,如为true,则状态为Valid;如为false,则为Invalid
void GoToState(bool isValid)
{
string visualState = isValid ? "Valid" : "Invalid";
//VisualStateManager.GoToState方法,设置控件状态,参数①为控件对象,参数②为状态的字符串值
VisualStateManager.GoToState(stackLayout, visualState);
}
}