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