MAUI新生4.2-样式外观:控件状态样式VisualState
(当前版本V7.0.94,VisualState有bug)
控件状态指控件当前处于什么使用状态,如禁用、聚焦、鼠标悬停等等,当控件进入到某种状态时,可以通过【附加属性】【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); } }
3、使用后台代码来自定义控件状态,还是比较麻烦。通过结合触发器,可以直接在XAML中定义触发状态改变的逻辑,使用更加简单方便。详见《MAUI新生5.3-样式外观:触发器Trigger》
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!