重新想象 Windows 8 Store Apps (15) - 控件 UI: 字体继承, Style, ControlTemplate, SystemResource, VisualState, VisualStateManager

原文: 重新想象 Windows 8 Store Apps (15) - 控件 UI: 字体继承, Style, ControlTemplate, SystemResource, VisualState, VisualStateManager

[源码下载]


重新想象 Windows 8 Store Apps (15) - 控件 UI: 字体继承, Style, ControlTemplate, SystemResource, VisualState, VisualStateManager



作者:webabcd


介绍
重新想象 Windows 8 Store Apps 之 控件 UI

  • 字体继承 - 继承父辈的 Font 相关的信息
  • Style - 样式
  • ControlTemplate - 控件模板
  • 系统资源 - 系统内置的样式资源
  • VisualState - 视图状态
  • VisualStateManager - 视图状态管理器



示例
1、演示字体继承
Controls/UI/FontInherit.xaml

<Page

    x:Class="XamlDemo.Controls.UI.FontInherit"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:XamlDemo.Controls.UI"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d"

    

    FontSize="100">



    <Grid Background="Transparent">

        <StackPanel Margin="120 0 0 0">

            

            <!--

                演示如何继承父辈的 Font 相关的信息

                Font 相关的设置来自 Windows.UI.Xaml.Controls.Control

            -->

            

            <!--

                继承了 Page 的关于 Font 的设置

            -->

            <TextBlock Text="FontSize = 100" />

            

            <UserControl FontSize="50">

                <!--

                    继承了 UserControl 的关于 Font 的设置

                -->

                <TextBlock Text="FontSize = 50" />

            </UserControl>

            

        </StackPanel>

    </Grid>

</Page>


2、演示 Style
Controls/UI/Style.xaml

<Page

    x:Class="XamlDemo.Controls.UI.Style"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:XamlDemo.Controls.UI"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d">



    <Grid Name="root" Background="Transparent">

        

        <!--

            注:

            1、在 Grid.Resources 指定的资源,其作用域仅在 Grid 之内,全局资源需要在 App.xaml 中配置

            2、Grid.Resources 等非全局资源也是支持 ResourceDictionary 的

        -->        

        <Grid.Resources>



            <!--

                Style - 样式

                    x:Key - 标识(不指定此值,则样式会应用于所有 TargetType 所指定的类型)

                    TargetType - 目标对象类型

                    BasedOn - 指定当前样式的父样式(此样式会继承指定的父样式)

                    Setter - 属性设置器

                        Property - 需要设置的属性名称

                        Value - 需要设置的属性值

            -->

            

            <Style x:Key="MyTextStyle" TargetType="TextBox">

                <Setter Property="FontSize" Value="24"/>

                <Setter Property="Foreground" Value="#0000FF"/>

            </Style>



            <Style x:Key="MyTextStyle2" TargetType="TextBox">

                <Setter Property="FontSize" Value="24"/>

                <Setter Property="Foreground" Value="#FF0000"/>

            </Style>



            <Style TargetType="TextBox" BasedOn="{StaticResource MyTextStyle}">

                <Setter Property="TextAlignment" Value="Center"/>

            </Style>

        </Grid.Resources>

        

        <StackPanel Margin="120 0 0 0">



            <!--通过指定样式资源,修改 FrameworkElement 的样式(Style 属性来自 FrameworkElement)-->

            <TextBox Name="txtStyleDemo" Text="我是 TextBox" Margin="5" Style="{StaticResource MyTextStyle}" />



            <!--隐式样式(即全局样式,即样式资源中未指定 key 的样式)的应用-->

            <TextBox Text="我是 TextBox" Margin="5" />



            <!--动态改变 FrameworkElement 的样式-->

            <Button Name="btnChangeStyle" Content="改变样式" Click="btnChangeStyle_Click_1" />



        </StackPanel>

    </Grid>

</Page>

Controls/UI/Style.xaml.cs

using Windows.UI.Xaml;

using Windows.UI.Xaml.Controls;



namespace XamlDemo.Controls.UI

{

    public sealed partial class Style : Page

    {

        public Style()

        {

            this.InitializeComponent();

        }



        private void btnChangeStyle_Click_1(object sender, RoutedEventArgs e)

        {

            // 获取 Application 中的资源

            // (Windows.UI.Xaml.Style)Application.Current.Resources["myStyle"];



            // 获取 root 内的资源

            txtStyleDemo.Style = (Windows.UI.Xaml.Style)root.Resources["MyTextStyle2"];

        }

    }

}


3、演示 ControlTemplate
Controls/UI/ControlTemplate.xaml

<Page

    x:Class="XamlDemo.Controls.UI.ControlTemplate"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:XamlDemo.Controls.UI"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d">



    <Grid Name="root" Background="Transparent">



        <!--

            注:

            1、在 Grid.Resources 指定的资源,其作用域仅在 Grid 之内,全局资源需要在 App.xaml 中配置

            2、Grid.Resources 等非全局资源也是支持 ResourceDictionary 的

        -->

        <Grid.Resources>



            <!--

                ControlTemplate - 控件模板

                    x:Key - 标识

                    TargetType - 目标对象类型

                ContentPresenter - 用于显示 ContentControl 中的 Content

                TemplateBinding - 模板绑定

            -->

            

            <ControlTemplate x:Key="MyControlTemplate" TargetType="Button">

                <Border BorderBrush="Red" BorderThickness="1">

                    <Grid Background="{TemplateBinding Background}">

                        <ContentPresenter HorizontalAlignment="Right" Foreground="Red" />

                    </Grid>

                </Border>

            </ControlTemplate>



            <ControlTemplate x:Key="MyControlTemplate2" TargetType="Button">

                <Border BorderBrush="Red" BorderThickness="1">

                    <Grid Background="{TemplateBinding Background}">

                        <ContentPresenter HorizontalAlignment="Right" Foreground="Blue" />

                    </Grid>

                </Border>

            </ControlTemplate>



            <!--在 Style 内配置 ControlTemplate-->

            <Style x:Key="MyStyle" TargetType="Button">

                <Setter Property="Template">

                    <Setter.Value>

                        <ControlTemplate TargetType="Button">

                            <Border BorderBrush="Red" BorderThickness="1">

                                <Grid Background="{TemplateBinding Background}">

                                    <ContentPresenter HorizontalAlignment="Right" Foreground="Red" />

                                </Grid>

                            </Border>

                        </ControlTemplate>

                    </Setter.Value>

                </Setter>

            </Style>

        </Grid.Resources>



        <StackPanel Margin="120 0 0 0">



            <!--通过指定控件模板资源,修改 Control 的模板(Template 属性来自 Control)-->

            <Button Name="btnControlTemplateDemo" Width="300" Margin="5" Content="我是 Button" Background="Yellow" Template="{StaticResource MyControlTemplate}" />



            <!--通过内联控件模板,修改 Control 的模板-->

            <Button Width="300" Margin="5" Content="我是 Button">

                <Button.Template>

                    <ControlTemplate>

                        <Border BorderBrush="Red" BorderThickness="1">

                            <Grid Background="Yellow">

                                <ContentPresenter HorizontalAlignment="Right" Foreground="Red" />

                            </Grid>

                        </Border>

                    </ControlTemplate>

                </Button.Template>

            </Button>



            <!--在 Style 内配置 ControlTemplate-->

            <Button Width="300" Margin="5" Content="我是 Button" Background="Yellow" Style="{StaticResource MyStyle}" />



            <!--动态改变 Control 的模板-->

            <Button Name="btnChangeControlTemplate" Content="改变控件模板" Click="btnChangeControlTemplate_Click_1" />



        </StackPanel>

    </Grid>

</Page>

Controls/UI/ControlTemplate.xaml.cs

using Windows.UI.Xaml;

using Windows.UI.Xaml.Controls;



namespace XamlDemo.Controls.UI

{

    public sealed partial class ControlTemplate : Page

    {

        public ControlTemplate()

        {

            this.InitializeComponent();

        }



        private void btnChangeControlTemplate_Click_1(object sender, RoutedEventArgs e)

        {

            // 获取 Application 中的资源

            // (Windows.UI.Xaml.Style)Application.Current.Resources["MyControlTemplate"];



            // 获取 root 内的资源

            btnControlTemplateDemo.Template = (Windows.UI.Xaml.Controls.ControlTemplate)root.Resources["MyControlTemplate2"];

        }

    }

}


4、演示如何使用系统内置的样式资源
Controls/UI/SystemResource.xaml

<Page

    x:Class="XamlDemo.Controls.UI.SystemResource"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:XamlDemo.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="120 0 0 0">



            <!--

                有 n 多的系统资源可用,以下举几个例子

            

                注:可以在 Visual Studio 中枚举出系统资源

            -->

            

            <Border Padding="12,4,12,4"

                    BorderThickness="{StaticResource ButtonBorderThemeThickness}" 

                    BorderBrush="{StaticResource ButtonBorderThemeBrush}" 

                    Background="{StaticResource ButtonBackgroundThemeBrush}">

                <TextBlock Text="我是一个长得像 Button 的 TextBlock" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="SemiBold"

                           FontFamily="{StaticResource ContentControlThemeFontFamily}" 

                           FontSize="{StaticResource ControlContentThemeFontSize}" 

                           Foreground="{StaticResource ButtonForegroundThemeBrush}" />

            </Border>



            <Button Content="我是一个 Button" Margin="0 10 0 0" />



        </StackPanel>

    </Grid>

</Page>


5、演示 VisualState 和 VisualStateManager 的应用
Controls/UI/VisualStateDemo.xaml

<Page

    x:Class="XamlDemo.Controls.UI.VisualStateDemo"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="using:XamlDemo.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">

        <Grid.Resources>



            <ControlTemplate x:Key="myControlTemplate" 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 - 鼠标经过时的状态

                            -->

                            <VisualState x:Name="PointerOver">

                                <Storyboard>

                                    <ColorAnimation 

                                        Storyboard.TargetName="borderBrush" 

                                        Storyboard.TargetProperty="Color" 

                                        To="Green" />

                                </Storyboard>

                            </VisualState>

                            <!--

                                PointerOver - 鼠标按下时的状态

                            -->

                            <VisualState x:Name="Pressed">

                                <Storyboard>

                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="grid">

                                        <DiscreteObjectKeyFrame KeyTime="0:0:0.3" Value="{StaticResource ButtonPressedBackgroundThemeBrush}"/>

                                    </ObjectAnimationUsingKeyFrames>

                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="contentPresenter">

                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonPressedForegroundThemeBrush}"/>

                                    </ObjectAnimationUsingKeyFrames>

                                </Storyboard>

                            </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="FocusStates">

                            <!--

                                Focused - 获取到焦点

                            -->

                            <VisualState x:Name="Focused" />

                            <!--

                                Unfocused - 失去焦点

                            -->

                            <VisualState x:Name="Unfocused"/>

                            <!--

                                PointerFocused - 通过指针获取到焦点

                            -->

                            <VisualState x:Name="PointerFocused"/>

                        </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="120 0 0 0">

            

            <Button Name="btnDemo" Content="我是 Button(用于演示 VisualState)" Margin="5" Background="Blue" Foreground="White" Template="{StaticResource myControlTemplate}" />



            <Button Name="btnVisualStateManager" Content="将上面的按钮的 VisualState 转到 PointerOver" Click="btnVisualStateManager_Click_1" Margin="5" />



        </StackPanel>

        

    </Grid>

</Page>

Controls/UI/VisualStateDemo.xaml.cs

/*

 * 演示 VisualState 和 VisualStateManager 的应用

 */



using Windows.UI.Xaml;

using Windows.UI.Xaml.Controls;



namespace XamlDemo.Controls.UI

{

    public sealed partial class VisualStateDemo : Page

    {

        public VisualStateDemo()

        {

            this.InitializeComponent();

        }



        private void btnVisualStateManager_Click_1(object sender, RoutedEventArgs e)

        {

            /*

             * bool GoToState(Control control, string stateName, bool useTransitions) - 转换 VisualState

             *     control - 需要转换 VisualState 的控件

             *     stateName - 目标 VisualState 的名称

             *     useTransitions - 是否使用 VisualTransition 进行过渡

             */



            // 将 VisualState 转到指定的状态

            VisualStateManager.GoToState(btnDemo, "PointerOver", true);

        }

    }

}



OK
[源码下载]

你可能感兴趣的:(template)