首页 > 代码库 > 控件 UI: VisualState, VisualStateManager, 控件的默认 UI

控件 UI: VisualState, VisualStateManager, 控件的默认 UI

VisualState 和 VisualStateManager

  • 控件的默认 Style, ControlTemplate, VisualState



示例
1、演示“VisualState 和 VisualStateManager”相关知识点
Controls/UI/VisualState/VisualStateDemo.xaml

<Page    x:Class="Windows10.Controls.UI.VisualState.VisualStateDemo"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:local="using:Windows10.Controls.UI.VisualState"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    mc:Ignorable="d">    <Grid Background="Transparent">        <Grid.Resources>            <!--                在 ControlTemplate 中定义 VisualState 和 VisualStateManager            -->            <ControlTemplate x:Key="ControlTemplate1" TargetType="Button">                <Grid>                    <VisualStateManager.VisualStateGroups>                        <!--                            VisualStateGroup - 用于分组 VisualState                        -->                        <VisualStateGroup x:Name="CommonStates">                                                        <!--                                Normal - 正常状态                                                            注意:                                1、本例所列出的 VisualState 的名称都是 Button 控件拥有的,不同的控件的 VisualState 名称和种类可能会不一样                                2、写自定义控件时,需要通过 VisualStateManager.GoToState() 来转换 VisualState                            -->                            <VisualState x:Name="Normal" />                                                        <!--                                Disabled - 无效状态                            -->                                                        <VisualState x:Name="Disabled" />                                                        <!--                                PointerOver - 鼠标经过时的状态(详细的过渡效果在后面的 VisualStateGroup.Transitions 中定义)                            -->                            <VisualState x:Name="PointerOver">                                <Storyboard>                                    <ColorAnimation                                         Storyboard.TargetName="borderBrush"                                         Storyboard.TargetProperty="Color"                                         To="Green" />                                </Storyboard>                            </VisualState>                                                        <!--                                Pressed - 鼠标按下时的状态                            -->                            <VisualState x:Name="Pressed">                                <VisualState.Storyboard>                                    <Storyboard>                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="grid">                                            <DiscreteObjectKeyFrame KeyTime="0:0:0.3" Value="http://www.mamicode.com/{StaticResource ButtonPressedBackgroundThemeBrush}"/>                                        </ObjectAnimationUsingKeyFrames>                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="contentPresenter">                                            <DiscreteObjectKeyFrame KeyTime="0" Value="http://www.mamicode.com/{StaticResource ButtonPressedForegroundThemeBrush}"/>                                        </ObjectAnimationUsingKeyFrames>                                    </Storyboard>                                </VisualState.Storyboard>                                <VisualState.Setters>                                    <!--                                        这部分是 uwp 新增的特性,以前只能通过 Storyboard 来实现                                    -->                                    <Setter Target="grid.Width" Value="http://www.mamicode.com/100" />                                </VisualState.Setters>                                <VisualState.StateTriggers>                                    <!--                                        这部分是 uwp 新增的特性                                        关于 StateTriggers 请参见 /Controls/UI/VisualState/StateTrigger.xaml                                    -->                                </VisualState.StateTriggers>                            </VisualState>                                                        <!--                                VisualTransition - VisualState 变化时的过渡效果                                    From - 变化前的 VisualState 的 Name                                    To - 变化后的 VisualState 的 Name                                    GeneratedDuration - 一个状态变化到另一个状态的所需时间                                    GeneratedEasingFunction - 一个状态变化到另一个状态的缓动效果                            -->                            <VisualStateGroup.Transitions>                                <VisualTransition To="PointerOver" GeneratedDuration="0:0:1">                                    <VisualTransition.GeneratedEasingFunction>                                        <ElasticEase EasingMode="EaseInOut" />                                    </VisualTransition.GeneratedEasingFunction>                                </VisualTransition>                            </VisualStateGroup.Transitions>                        </VisualStateGroup>                        <VisualStateGroup x:Name="MyStates">                            <VisualState x:Name="MyState1" />                            <VisualState x:Name="MyState2"/>                            <VisualState x:Name="MyState3"/>                        </VisualStateGroup>                                            </VisualStateManager.VisualStateGroups>                    <Border x:Name="border" BorderThickness="10">                        <Border.BorderBrush>                            <SolidColorBrush x:Name="borderBrush" Color="Red" />                        </Border.BorderBrush>                        <Grid Name="grid" Background="{TemplateBinding Background}" Width="500" Height="200">                            <ContentPresenter Name="contentPresenter" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="24.667"                                           Foreground="{TemplateBinding Foreground}" />                        </Grid>                    </Border>                </Grid>            </ControlTemplate>        </Grid.Resources>        <StackPanel Margin="10 0 10 10">            <TextBlock Name="lblMsg" TextWrapping="Wrap" Margin="5" />            <Button Name="btnDemo" Content="我是 Button(用于演示 VisualState 和 VisualStateManager)" Margin="5" Background="Blue" Foreground="White" Template="{StaticResource ControlTemplate1}" />            <Button Name="btnVisualStateManager" Content="将上面的按钮的 VisualState 转到 PointerOver" Click="btnVisualStateManager_Click" Margin="5" />        </StackPanel>    </Grid></Page>

Controls/UI/VisualState/VisualStateDemo.xaml.cs

/* * 演示“VisualState 和 VisualStateManager”相关知识点 */using System;using System.Collections.Generic;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows10.Common;namespace Windows10.Controls.UI.VisualState{    public sealed partial class VisualStateDemo : Page    {        public VisualStateDemo()        {            this.InitializeComponent();        }        private void btnVisualStateManager_Click(object sender, RoutedEventArgs e)        {            /*             * bool GoToState(Control control, string stateName, bool useTransitions) - 转换 VisualState             *     control - 需要转换 VisualState 的控件             *     stateName - 目标 VisualState 的名称             *     useTransitions - 是否使用 VisualTransition 进行过渡             */            // 将 VisualState 转到指定的状态(每个 VisualStateGroup 分别指定一个其内的 VisualState)            VisualStateManager.GoToState(btnDemo, "PointerOver", true);            VisualStateManager.GoToState(btnDemo, "MyState3", false);            /*             * VisualStateManager.GetVisualStateGroups(FrameworkElement obj) - 获取指定 FrameworkElement 中的 VisualStateGroup 集合             *     注:本例中的 VisualState 定义在 btnDemo 的控件模板中的第一个 Grid 中             *             * VisualStateGroup - VisualState 组(每个 VisualStateManager 下可以有多个 VisualStateGroup)             *     Name - 获取此 VisualStateGroup 的名字             *     CurrentState - 获取此 VisualStateGroup 的当前使用的 VisualState(每个 VisualStateGroup 正在使用的 VisualState 只能有一个)             *     States - 获取此 VisualStateGroup 中的 VisualState 集合             *     Transitions - 获取此 VisualStateGroup 中的 VisualTransition 集合             *     CurrentStateChanging, CurrentStateChanged - 此 VisualStateGroup 中的正在使用的 VisualState 发生变化时触发的事件             *             * VisualState - VisualState             *     Name - 获取此 VisualState 的名字             *     Setters - 获取此 VisualState 中的 Setter 集合             *     StateTriggers - 获取此 VisualState 中的 StateTrigger 集合             *     Storyboard - 获取此 VisualState 中的 Storyboard 对象             */            lblMsg.Text = "";            Grid grid = Helper.GetVisualChild<Grid>(btnDemo);            IList<VisualStateGroup> visualStateGroups = VisualStateManager.GetVisualStateGroups(grid);            foreach (VisualStateGroup visualStateGroup in visualStateGroups)            {                lblMsg.Text += visualStateGroup.Name + " " + visualStateGroup.CurrentState.Name;                lblMsg.Text += Environment.NewLine;            }        }    }}


2、演示如何获取控件的默认 Style, ControlTemplate, VisualState
Controls/UI/DefaultUI.xaml

<Page    x:Class="Windows10.Controls.UI.DefaultUI"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:local="using:Windows10.Controls.UI"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    mc:Ignorable="d">    <Grid Background="Transparent">        <StackPanel Margin="10 0 10 10">            <TextBlock TextWrapping="Wrap" Margin="5">                <Run>如何获取控件的默认 Style, ControlTemplate, VisualState 呢?</Run>                <LineBreak />                <Run>1、在 msdn 上找: https://msdn.microsoft.com/zh-cn/library/windows/apps/xaml/mt299122.aspx</Run>                <LineBreak />                <Run>2、在 Visual Studio 的设计界面,右键选择控件,然后选择“编辑控件”或“编辑模板”或“编辑其他模板”,然后选择“编辑副本”</Run>                <LineBreak />                <Run>3、打开这个 C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.10586.0\Generic\generic.xaml 文件,然后在里面找</Run>            </TextBlock>            <TextBlock TextWrapping="Wrap" Margin="5">                <Run>如果遇到复杂的控件,如何确定我要编辑的其内部的控件的类型呢?</Run>                <LineBreak />                <Run>运行你的程序,然后在“实时可视化树(Live Visual Tree)”中找</Run>            </TextBlock>        </StackPanel>    </Grid>    <Page.Resources>        <!--            这个就是 Button 的默认样式        -->        <Style x:Key="ButtonStyle1" TargetType="Button">            <Setter Property="Background" Value="http://www.mamicode.com/{ThemeResource SystemControlBackgroundBaseLowBrush}"/>            <Setter Property="Foreground" Value="http://www.mamicode.com/{ThemeResource SystemControlForegroundBaseHighBrush}"/>            <Setter Property="BorderBrush" Value="http://www.mamicode.com/{ThemeResource SystemControlForegroundTransparentBrush}"/>            <Setter Property="BorderThickness" Value="http://www.mamicode.com/{ThemeResource ButtonBorderThemeThickness}"/>            <Setter Property="Padding" Value="http://www.mamicode.com/8,4,8,4"/>            <Setter Property="HorizontalAlignment" Value="http://www.mamicode.com/Left"/>            <Setter Property="VerticalAlignment" Value="http://www.mamicode.com/Center"/>            <Setter Property="FontFamily" Value="http://www.mamicode.com/{ThemeResource ContentControlThemeFontFamily}"/>            <Setter Property="FontWeight" Value="http://www.mamicode.com/Normal"/>            <Setter Property="FontSize" Value="http://www.mamicode.com/{ThemeResource ControlContentThemeFontSize}"/>            <Setter Property="UseSystemFocusVisuals" Value="http://www.mamicode.com/True"/>            <Setter Property="Template">                <Setter.Value>                    <ControlTemplate TargetType="Button">                        <Grid x:Name="RootGrid" Background="{TemplateBinding Background}">                            <VisualStateManager.VisualStateGroups>                                <VisualStateGroup x:Name="CommonStates">                                    <VisualState x:Name="Normal">                                        <Storyboard>                                            <PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>                                        </Storyboard>                                    </VisualState>                                    <VisualState x:Name="PointerOver">                                        <Storyboard>                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">                                                <DiscreteObjectKeyFrame KeyTime="0" Value="http://www.mamicode.com/{ThemeResource SystemControlHighlightBaseMediumLowBrush}"/>                                            </ObjectAnimationUsingKeyFrames>                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">                                                <DiscreteObjectKeyFrame KeyTime="0" Value="http://www.mamicode.com/{ThemeResource SystemControlHighlightBaseHighBrush}"/>                                            </ObjectAnimationUsingKeyFrames>                                            <PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>                                        </Storyboard>                                    </VisualState>                                    <VisualState x:Name="Pressed">                                        <Storyboard>                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">                                                <DiscreteObjectKeyFrame KeyTime="0" Value="http://www.mamicode.com/{ThemeResource SystemControlBackgroundBaseMediumLowBrush}"/>                                            </ObjectAnimationUsingKeyFrames>                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">                                                <DiscreteObjectKeyFrame KeyTime="0" Value="http://www.mamicode.com/{ThemeResource SystemControlHighlightTransparentBrush}"/>                                            </ObjectAnimationUsingKeyFrames>                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">                                                <DiscreteObjectKeyFrame KeyTime="0" Value="http://www.mamicode.com/{ThemeResource SystemControlHighlightBaseHighBrush}"/>                                            </ObjectAnimationUsingKeyFrames>                                            <PointerDownThemeAnimation Storyboard.TargetName="RootGrid"/>                                        </Storyboard>                                    </VisualState>                                    <VisualState x:Name="Disabled">                                        <Storyboard>                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="RootGrid">                                                <DiscreteObjectKeyFrame KeyTime="0" Value="http://www.mamicode.com/{ThemeResource SystemControlBackgroundBaseLowBrush}"/>                                            </ObjectAnimationUsingKeyFrames>                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">                                                <DiscreteObjectKeyFrame KeyTime="0" Value="http://www.mamicode.com/{ThemeResource SystemControlDisabledBaseMediumLowBrush}"/>                                            </ObjectAnimationUsingKeyFrames>                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ContentPresenter">                                                <DiscreteObjectKeyFrame KeyTime="0" Value="http://www.mamicode.com/{ThemeResource SystemControlDisabledTransparentBrush}"/>                                            </ObjectAnimationUsingKeyFrames>                                        </Storyboard>                                    </VisualState>                                </VisualStateGroup>                            </VisualStateManager.VisualStateGroups>                            <ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>                        </Grid>                    </ControlTemplate>                </Setter.Value>            </Setter>        </Style>    </Page.Resources></Page>

控件 UI: VisualState, VisualStateManager, 控件的默认 UI