[源码下载]

背水一战 Windows 10 (8) - 控件 UI: StateTrigger

作者:webabcd

介绍
背水一战 Windows 10 之 控件 UI

  • 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>

OK
[源码下载]

背水一战 Windows 10 (8) - 控件 UI: StateTrigger的更多相关文章

  1. 背水一战 Windows 10 (7) - 控件 UI: VisualState, VisualStateManager, 控件的默认 UI

    [源码下载] 背水一战 Windows 10 (7) - 控件 UI: VisualState, VisualStateManager, 控件的默认 UI 作者:webabcd 介绍背水一战 Wind ...

  2. 背水一战 Windows 10 (6) - 控件 UI: 字体的自动继承的特性, Style, ControlTemplate

    [源码下载] 背水一战 Windows 10 (6) - 控件 UI: 字体的自动继承的特性, Style, ControlTemplate 作者:webabcd 介绍背水一战 Windows 10 ...

  3. 背水一战 Windows 10 (37) - 控件(弹出类): MessageDialog, ContentDialog

    [源码下载] 背水一战 Windows 10 (37) - 控件(弹出类): MessageDialog, ContentDialog 作者:webabcd 介绍背水一战 Windows 10 之 控 ...

  4. 背水一战 Windows 10 (36) - 控件(弹出类): ToolTip, Popup, PopupMenu

    [源码下载] 背水一战 Windows 10 (36) - 控件(弹出类): ToolTip, Popup, PopupMenu 作者:webabcd 介绍背水一战 Windows 10 之 控件(弹 ...

  5. 背水一战 Windows 10 (35) - 控件(弹出类): FlyoutBase, Flyout, MenuFlyout

    [源码下载] 背水一战 Windows 10 (35) - 控件(弹出类): FlyoutBase, Flyout, MenuFlyout 作者:webabcd 介绍背水一战 Windows 10 之 ...

  6. 背水一战 Windows 10 (34) - 控件(进度类): RangeBase, Slider, ProgressBar, ProgressRing

    [源码下载] 背水一战 Windows 10 (34) - 控件(进度类): RangeBase, Slider, ProgressBar, ProgressRing 作者:webabcd 介绍背水一 ...

  7. 背水一战 Windows 10 (33) - 控件(选择类): ListBox, RadioButton, CheckBox, ToggleSwitch

    [源码下载] 背水一战 Windows 10 (33) - 控件(选择类): ListBox, RadioButton, CheckBox, ToggleSwitch 作者:webabcd 介绍背水一 ...

  8. 背水一战 Windows 10 (32) - 控件(选择类): Selector, ComboBox

    [源码下载] 背水一战 Windows 10 (32) - 控件(选择类): Selector, ComboBox 作者:webabcd 介绍背水一战 Windows 10 之 控件(选择类) Sel ...

  9. 背水一战 Windows 10 (31) - 控件(按钮类): ButtonBase, Button, HyperlinkButton, RepeatButton, ToggleButton, AppBarButton, AppBarToggleButton

    [源码下载] 背水一战 Windows 10 (31) - 控件(按钮类): ButtonBase, Button, HyperlinkButton, RepeatButton, ToggleButt ...

随机推荐

  1. 创建ABPboilerplate模版项目

    本文是根据角落的白板报的<通过ABPboilerplate模版创建项目>一文的学习总结,感谢原文作者角落的白板报. 1 准备 开发环境: Visual Studio 2015 update ...

  2. iOS 获取设备唯一标示符的方法

    在开发中会遇到应用需要记录设备标示,即使应用卸载后再安装也可重新识别的情况,在这写一种实现方式--读取设备的UUID(Universally Unique Identifier)并通过KeyChain ...

  3. 【WPF】整个自定义按钮后台添加

  4. 数据库设计(2/9):域,约束和默认值(Domains, Constraints and Defaults)

    对于设计和创建数据库完全是个新手?没关系,Joe Celko, 世界上读者数量最多的SQL作者之一,会告诉你这些基础.和往常一样,即使是最专业的数据库老手,也会给他们带来惊喜.Joe是DMBS杂志是多 ...

  5. 《DSP using MATLAB》示例Example5.14

    代码: x1 = [1,2,2]; x2 = [1,2,3,4]; y = circonvt(x1,x2,4) n1 = 0:1:length(x1)-1; n2 = 0:1:length(x2)-1 ...

  6. 网络模拟器WANem使用配置图文教程

    转自:http://blog.csdn.net/zm_21/article/details/25810263 WANem简介 由于公司在一些场合需要模拟真实的网络环境,如时延,丢包,抖动等,虽然使用L ...

  7. jQuery点缩略图显示大图片

    2015年繁忙的一月份,无更多时间去学习ASP.NET MVC程序,二月份又是中国的新年,长达半个月的假期,望回到老家中,在无电脑无网络的日子里,能有更多时间陪伴年迈的父母亲. 今天学习jQuery的 ...

  8. JS-面向对象-封装

    --参考文献: --http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html --js面 ...

  9. Emmet 的使用

    Emmet 的介绍 Emmet 的前身叫做:Zen Coding,也许熟知旧名的人不在少数.Emmet 一般前端工程师用得比较多,具体它是做什么的,我们通过下面两张 Gif 演示图来说明: Intel ...

  10. 【BZOJ1010】【HNOI2008】玩具装箱

    继续看黄学长代码 原题: P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1.. ...