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》

posted @ 2022-12-09 22:28  functionMC  阅读(753)  评论(0编辑  收藏  举报