zoukankan      html  css  js  c++  java
  • 控件 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="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="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="{StaticResource MyTextStyle}" />
                            <Setter Target="myTextBlock2.Style" Value="{StaticResource MyTextStyle}" />
                            <Setter Target="myTextBlock3.Style" Value="{StaticResource MyTextStyle}" />
                            <Setter Target="myButton.Template" Value="{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="#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="Orange" />
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
    
        </Grid>
    
    </Page>
  • 相关阅读:
    我藏在你的心里,你却不愿意寻找# BUG躲猫猫
    阴间需求之跨端登录
    神奇的props
    map与filter:你先我先?
    阴间BUG之动态路由刷新几率回首页
    阴间BUG之动态路由添加失败
    我在eltable就变了个模样,请你不要再想我,想起我
    SCP打包部署方法
    indexOf 与 includes
    YACC和BISON学习心得
  • 原文地址:https://www.cnblogs.com/ansen312/p/5913512.html
Copyright © 2011-2022 走看看