重新想象 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 ...
原文: 重新想象 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
[源码下载]

目录
相关文章
|
Linux C++ Windows
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
138 0
【Azure 应用服务】Azure App Service(Windows)环境中如何让.NET应用调用SAP NetWeaver RFC函数
|
10月前
|
C# Windows
【Azure App Service】在App Service for Windows上验证能占用的内存最大值
根据以上测验,当使用App Service内存没有达到预期的值,且应用异常日志出现OutOfMemory时,就需要检查Platform的设置是否位64bit。
160 11
|
Java 应用服务中间件 开发工具
[App Service for Windows]通过 KUDU 查看 Tomcat 配置信息
[App Service for Windows]通过 KUDU 查看 Tomcat 配置信息
133 2
|
Java 应用服务中间件 Windows
【App Service for Windows】为 App Service 配置自定义 Tomcat 环境
【App Service for Windows】为 App Service 配置自定义 Tomcat 环境
114 2
|
PHP Windows
【Azure App Service for Windows】 PHP应用出现500 : The page cannot be displayed because an internal server error has occurred. 错误
【Azure App Service for Windows】 PHP应用出现500 : The page cannot be displayed because an internal server error has occurred. 错误
209 1
|
PHP 开发工具 git
【Azure 应用服务】在 App Service for Windows 中自定义 PHP 版本的方法
【Azure 应用服务】在 App Service for Windows 中自定义 PHP 版本的方法
118 1
|
网络安全 API 数据安全/隐私保护
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Windows)
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Windows)
114 0
|
Shell PHP Windows
【Azure App Service】Web Job 报错 UNC paths are not supported. Defaulting to Windows directory.
【Azure App Service】Web Job 报错 UNC paths are not supported. Defaulting to Windows directory.
109 0
|
存储 Linux Windows
【应用服务 App Service】App Service For Windows 如何挂载Storage Account File Share 示例
【应用服务 App Service】App Service For Windows 如何挂载Storage Account File Share 示例
113 0
|
应用服务中间件 nginx Windows
【Azure 应用服务】在App Service for Windows中实现反向代理
【Azure 应用服务】在App Service for Windows中实现反向代理
131 0

热门文章

最新文章