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


[源碼下載]


背水一戰 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
[源碼下載]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM