首页 > 代码库 > 控件 UI: StateTrigger

控件 UI: StateTrigger

VisualState 之 StateTrigger



示例
1、自定义 StateTrigger
Controls/UI/VisualState/MyDeviceFamilyStateTrigger.cs

/* * 用于演示自定义 StateTrigger * * * StateTriggerBase - 自定义 StateTrigger 需要继承此基类 *     SetActive(Boolean IsActive) - 调用此方法,传递 true 则应用对应的 VisualState;传递 false 则取消对应的 VisualState * * * 此类的作用:当前的设备类型与指定的一致时,则触发对应的 VisualState * 注:如果 DeviceFamily 属性需要绑定的话,别忘了将其定义为依赖属性 */using Windows.UI.Xaml;namespace Windows10.Controls.UI.VisualState{    public class MyDeviceFamilyStateTrigger : StateTriggerBase    {        private string _deviceFamily;        public string DeviceFamily        {            get            {                return _deviceFamily;            }            set            {                _deviceFamily = value;                // 获取当前的设备类型,目前已知的返回字符串有:Windows.Mobile, Windows.Desktop, Windows.Xbox                string currentDeviceFamily = Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily;                // 当前的设备类型与指定的一致则触发对应的 VisualState                SetActive(_deviceFamily == currentDeviceFamily);            }        }    }}


2、自定义 StateTrigger
Controls/UI/VisualState/MyInputTypeStateTrigger.cs

/* * 用于演示自定义 StateTrigger * * * StateTriggerBase - 自定义 StateTrigger 需要继承此基类 *     SetActive(Boolean IsActive) - 调用此方法,传递 true 则应用对应的 VisualState;传递 false 则取消对应的 VisualState * * * 此类的作用:当指定的 FrameworkElement 触发 PointerPressedEvent 事件时,根据 PointerDeviceType 的不同触发不同的 VisualState * 注:如果 TargetElement 属性或 PointerType 属性需要绑定的话,别忘了将其定义为依赖属性 */using Windows.Devices.Input;using Windows.UI.Xaml;using Windows.UI.Xaml.Input;namespace Windows10.Controls.UI.VisualState{    public class MyInputTypeStateTrigger : StateTriggerBase    {        private FrameworkElement _targetElement;        private PointerDeviceType _lastPointerType, _triggerPointerType;        private PointerEventHandler _pointerEventHandler;        // 指定的 FrameworkElement        public FrameworkElement TargetElement        {            get            {                return _targetElement;            }            set            {                if (_pointerEventHandler == null)                {                    _pointerEventHandler = new PointerEventHandler(_targetElement_PointerPressed);                }                if (_targetElement != null)                {                    _targetElement.RemoveHandler(FrameworkElement.PointerPressedEvent, _pointerEventHandler);                }                _targetElement = value;                // 监听 FrameworkElement 的 PointerPressedEvent 事件                _targetElement.AddHandler(FrameworkElement.PointerPressedEvent, _pointerEventHandler, true);                // 这么写有问题,因为点击 button 时不会触发此事件                // _targetElement.PointerPressed += _targetElement_PointerPressed;            }        }        private void _targetElement_PointerPressed(object sender, PointerRoutedEventArgs e)        {            _lastPointerType = e.Pointer.PointerDeviceType;            UpdateTrigger();        }        // 指定的 PointerDeviceType(Touch, Pen, Mouse)        public PointerDeviceType PointerType        {            get            {                return _triggerPointerType;            }            set            {                _triggerPointerType = value;            }        }        public void UpdateTrigger()        {            // 指定的 FrameworkElement 触发 PointerPressedEvent 事件后,其 PointerDeviceType 如果和指定的 PointerDeviceType 一致,则触发对应的 VisualState            SetActive(_triggerPointerType == _lastPointerType);        }    }}


3、演示 StateTrigger 的应用
Controls/UI/VisualState/StateTrigger.xaml

<Page    x:Class="Windows10.Controls.UI.VisualState.StateTrigger"    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"        xmlns:custom="using:Windows10.Controls.UI.VisualState" >    <!--        本例用于演示 StateTrigger 的应用,以及如何自定义 StateTrigger        StateTrigger 的作用就是:当指定的条件达成时触发对应的 VisualState        内置的 StateTrigger 一共有两个,分别是 AdaptiveTrigger 和 StateTrigger,他们都继承自 StateTriggerBase    -->    <Page.Resources>        <Style x:Key="MyTextStyle" TargetType="TextBlock" BasedOn="{StaticResource MyTextBlockStyle}">            <Setter Property="FontSize" Value="http://www.mamicode.com/24"/>        </Style>        <ControlTemplate x:Key="MyControlTemplate" TargetType="Button">            <Border BorderBrush="Red" BorderThickness="1">                <Grid Background="{TemplateBinding Background}">                    <ContentPresenter Foreground="Red" />                </Grid>            </Border>        </ControlTemplate>    </Page.Resources>    <Grid x:Name="myGrid" Background="Transparent">        <StackPanel Name="myPanel" Orientation="Horizontal" Margin="10 0 10 10">            <TextBlock Text="TextBlock 1 " Name="myTextBlock1" Margin="10" />            <TextBlock Text="TextBlock 2 " Name="myTextBlock2" Margin="10" />            <TextBlock Text="TextBlock 3 " Name="myTextBlock3" Margin="10" />            <Button Name="myButton" Content="我是 Button" Margin="10" />            <CheckBox Name="chkIsActive" Content="IsActive" Margin="10" />        </StackPanel>        <!--注意:VisualState 不能放到 Page 下面,否则不工作-->        <VisualStateManager.VisualStateGroups>            <!--                给 VisualState 分组是很有必要的,每个 VisualStateGroup 正在使用的 VisualState 只能有一个            -->            <VisualStateGroup x:Name="WindowSizeStates">                <VisualState>                    <VisualState.StateTriggers>                        <!--                            AdaptiveTrigger - 内置的 StateTrigger                                MinWindowWidth - 当窗口的宽度大于等于此值时触发(依赖属性)                                MinWindowHeight - 当窗口的高度大于等于此值时触发(依赖属性)                        -->                        <!--当窗口的的宽度大于等于 720 时,触发此 VisualState(这里没有对应的 VisualState,也就是都恢复为默认状态)-->                        <AdaptiveTrigger MinWindowWidth="720" />                    </VisualState.StateTriggers>                </VisualState>                <VisualState>                    <VisualState.StateTriggers>                        <!--当窗口的的宽度大于等于 0 时且小于 720 时,触发此 VisualState-->                        <AdaptiveTrigger MinWindowWidth="0" />                    </VisualState.StateTriggers>                    <VisualState.Setters>                        <Setter Target="myPanel.Orientation" Value="http://www.mamicode.com/Vertical" />                    </VisualState.Setters>                </VisualState>            </VisualStateGroup>            <VisualStateGroup x:Name="ActiveStates">                <VisualState>                    <VisualState.StateTriggers>                        <!--                            StateTrigger - 内置的 StateTrigger                                IsActive - 是否触发对应的 VisualState(依赖属性)                        -->                        <!--根据复选框 chkIsActive 的选中状态,来决定是否触发此 VisualState-->                        <StateTrigger IsActive="{Binding ElementName=chkIsActive, Path=IsChecked, Mode=OneWay}" />                    </VisualState.StateTriggers>                    <VisualState.Setters>                        <Setter Target="myTextBlock1.Style" Value="http://www.mamicode.com/{StaticResource MyTextStyle}" />                        <Setter Target="myTextBlock2.Style" Value="http://www.mamicode.com/{StaticResource MyTextStyle}" />                        <Setter Target="myTextBlock3.Style" Value="http://www.mamicode.com/{StaticResource MyTextStyle}" />                        <Setter Target="myButton.Template" Value="http://www.mamicode.com/{StaticResource MyControlTemplate}" />                    </VisualState.Setters>                </VisualState>            </VisualStateGroup>            <VisualStateGroup x:Name="DeviceFamilyStates">                <VisualState>                    <VisualState.StateTriggers>                        <!--                            MyDeviceFamilyStateTrigger - 自定义的 StateTrigger                                DeviceFamily - 当设备类型为指定的值时触发(非依赖属性,如需绑定之类的特性的话,则要将其改为依赖属性)                        -->                        <!--当设备类型为 Windows.Desktop 时触发此 VisualState-->                        <custom:MyDeviceFamilyStateTrigger DeviceFamily="Windows.Desktop" />                    </VisualState.StateTriggers>                    <VisualState.Setters>                        <Setter Target="myGrid.Background" Value="http://www.mamicode.com/#FF0000" />                    </VisualState.Setters>                </VisualState>            </VisualStateGroup>            <VisualStateGroup x:Name="InputTypeStates">                <VisualState>                    <!--                        MyInputTypeStateTrigger - 自定义的 StateTrigger                            TargetElement - 需要监听 PointerPressedEvent 事件的 FrameworkElement 对象(非依赖属性,如需绑定之类的特性的话,则要将其改为依赖属性)                            PointerType - 监听的 FrameworkElement 触发 PointerPressedEvent 事件后,根据 PointerType 的类型来决定触发指定的 VisualState(非依赖属性,如需绑定之类的特性的话,则要将其改为依赖属性)                    -->                    <!--当触发了 myButton 的 PointerPressedEvent 事件后,如果其 PointerDeviceType 是 Mouse 类型,则触发此 VisualState-->                    <VisualState.StateTriggers>                        <!--对 {x:Bind myButton} 不理解的话,请参见“绑定”部分-->                        <custom:MyInputTypeStateTrigger TargetElement="{x:Bind myButton}" PointerType="Mouse" />                    </VisualState.StateTriggers>                    <VisualState.Setters>                        <Setter Target="myGrid.Background" Value="http://www.mamicode.com/Orange" />                    </VisualState.Setters>                </VisualState>            </VisualStateGroup>        </VisualStateManager.VisualStateGroups>    </Grid></Page>

控件 UI: StateTrigger