Blend 2015 教程 (二) 样式
前一篇讲述了如何在新Blend中完成一个简单的带数据绑定的界面小例子,本篇将讲述一下,把View层和Style层分开,并搭建Style层框架的方法,并进行细节样式修改。
1. 在解决方案资源管理器面板的项目结构树中的项目项(标有图标C#)上右键点击,选择 添加-新建文件夹,起名为Styles。在刚添加的Styles文件夹上右键点击,选择 添加-资源字典,起名为CoreStyle.xaml,点击确定。再添加一个,起名为BaseStyle.xaml。
2. 打开MainWindow.xaml,选择人员列表TextBlock,在属性面板中点击字体和字号的小方块(小方块为蓝色,说明是样式起作用),选择转换为本地值。点击Style属性的小方块,选择重置。在文档大纲面板中右键点击人员列表TextBlock,在弹出菜单中选择 编辑样式-创建空样式,起名为TitleTextStyle,在定义位置中应该选择第三个选项,再选择我们刚才创建的资源字典BaseStyle.xaml,但发现第三个选项是灰的,点击新建也不能使用,可能是Preview版的BUG,只能暂且选择第二个选项本文档,点击确定,此时进入样式编辑模式。
点击字体的小方块,选择转换为新资源,起名TitleFontFamily,在定义位置中选择第二个选项,点击确定。点击字号的小方块,选择转换为新资源,起名TitleFontSize,在定义位置中选择第二个选项,点击确定。
这里创建了一个两层的样式框架,底层为核心层,为应用程序的核心字体,字号,前景颜色,背景颜色等的定义,上一层为文本块等基础元素的样式定义,视为基础层,会引用核心层的定义。第三层就应该为复杂控件的样式了,其引用基础层的定义,或直接引用核心层的定义。这样做的好处是一旦修改应用程序的核心样式定义,如字体,字号等,一般只需修改核心层的定义,不用改其他的地方,甚至可以在运行时动态修改,因为Blend默认把这些资源引用都作为动态资源引用。
3. 点击文档大纲面板的退到上一层按钮,退出样式编辑模式。选择ListBox,点击美工板导航栏的ListBox,选择 编辑其他模板-编辑生成的项-编辑当前项。在美工板中选择TextBlock,使用和上述相同的方法,为TextBlock创建新样式,起名为CoreTextStyle。
这时美工板导航栏变为如下图,
表示正在编辑ListBox控件的模板中的TextBlock的样式,这个需要理解。
在属性面板中把字体改为SimSun,字号改为16 px,再把字体和字号转换为新资源,起名为CoreFontFamily和CoreFontSize。
4. 点击文档大纲面板的返回上一层按钮,然后选择CheckBox控件,为其创建新样式,起名为CheckBoxBaseStyle,此时需要点击主菜单 格式-编辑样式-创建空白项,名称改为CheckBoxBaseStyle,点击确定。在属性面板中点击字体的小方块,选择 本地资源-CoreFontFamily,点击字号的小方块,选择 本地资源-CoreFontSize。
5. 至此字体字号的抽取工作已经基本完成,也可针对前景色进行抽取。
设计器呈现效果如下,
代码如下,
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:BlendDemo" xmlns:System="clr-namespace:System;assembly=mscorlib" x:Class="BlendDemo.MainWindow" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525" d:DataContext="{d:DesignData /SampleData/SampleDataSource/SampleDataSource.xaml}"> <Window.Resources> <Style x:Key="TextBlockStyle1" TargetType="{x:Type TextBlock}"> <Setter Property="FontFamily" Value="SimHei"/> <Setter Property="FontSize" Value="22"/> </Style> <DataTemplate x:Key="DataTemplate1"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBlock Height="Auto" TextWrapping="Wrap" Text="{Binding Name}" Width="Auto" Style="{DynamicResource CoreTextStyle}"/> <CheckBox Content="男" Grid.Column="1" Height="Auto" Width="Auto" IsChecked="{Binding Sex}" Style="{DynamicResource CheckBoxBaseStyle}"/> </Grid> </DataTemplate> <FontFamily x:Key="TitleFontFamily">SimHei</FontFamily> <System:Double x:Key="TitleFontSize">22</System:Double> <Style x:Key="TitleTextStyle" TargetType="{x:Type TextBlock}"> <Setter Property="FontFamily" Value="{DynamicResource TitleFontFamily}"/> <Setter Property="FontSize" Value="{DynamicResource TitleFontSize}"/> </Style> <FontFamily x:Key="CoreFontFamily">SimSun</FontFamily> <System:Double x: Key="CoreFontSize">16</System:Double> <Style x:Key="CoreTextStyle" TargetType="{x:Type TextBlock}"> <Setter Property="FontFamily" Value="{DynamicResource CoreFontFamily}"/> <Setter Property="FontSize" Value="{DynamicResource CoreFontSize}"/> </Style> <Style x:Key="CheckBoxBaseStyle" TargetType="{x:Type CheckBox}"> <Setter Property="FontFamily" Value="{DynamicResource CoreFontFamily}"/> <Setter Property="FontSize" Value="{DynamicResource CoreFontSize}"/> </Style> </Window.Resources> <Grid > <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <TextBlock Text="人员列表" Margin="10" Style ="{DynamicResource TitleTextStyle}"/> <ListBox Grid.Row="1" ItemsSource="{Binding Persons}" ItemTemplate="{DynamicResource DataTemplate1}" HorizontalContentAlignment="Stretch"/> </Grid > </Window>
由于前文所说的那个BUG,现在样式和资源都在本文件中,没有直接放入他们该在的地方。下面使用资源面板对资源进行一下重新组织。目前资源面板如下图,
将TextBlockStyle1删除(点击右键,在弹出菜单中选择删除),将DataTemplate1重命名为PeopleListBoxDataTemplate,重命名的方法是,在选中该资源的条件下,在资源名称上左键单击,此时变为编辑状态,可修改或粘贴,焦点离开时会弹出如下所示对话框,
问是否更新引用,选择更新引用,点击继续完成修改。
6. 在App.xaml上右键单击,在弹出菜单中选择 链接到资源字典-CoreStyle.xaml,把CoreStyle.xaml作为全局资源字典引用,使用同样的方法把BaseStyle.xaml也作为全局资源字典引用。
把MainWindow.xaml下的Window下的TitleFontFamily,TitleFontSize,CoreFontFamily,CoreFontSize四个资源拖动到CoreStyle.xaml中,把TitleTextStyle,CoreTextStyle,CheckBoxBaseStyle三个资源拖动到BaseStyle.xaml中。
至此,样式框架已经搭建好了。
代码如下,
MainWindow.xaml
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:BlendDemo" xmlns:System="clr-namespace:System;assembly=mscorlib" x:Class="BlendDemo.MainWindow" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525" d:DataContext="{d:DesignData /SampleData/SampleDataSource/SampleDataSource.xaml}"> <Window.Resources> <DataTemplate x :Key="PeopleListDataTemplate"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBlock Height="Auto" TextWrapping="Wrap" Text="{Binding Name}" Width="Auto" Style="{DynamicResource CoreTextStyle}"/> <CheckBox Content="男" Grid.Column="1" Height="Auto" Width ="Auto" IsChecked="{Binding Sex}" Style="{DynamicResource CheckBoxBaseStyle}"/> </Grid> </DataTemplate> </Window.Resources> <Grid > <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <TextBlock Text="人员列表" Margin="10" Style ="{DynamicResource TitleTextStyle}"/> <ListBox Grid.Row="1" ItemsSource="{Binding Persons}" ItemTemplate="{DynamicResource PeopleListDataTemplate}" HorizontalContentAlignment="Stretch"/> </Grid > </Window>
CoreStyle.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:BlendDemo" xmlns:System="clr-namespace:System;assembly=mscorlib"> <FontFamily x:Key="TitleFontFamily">SimHei</FontFamily> <System:Double x:Key="TitleFontSize">22</System:Double> <FontFamily x:Key="CoreFontFamily">SimSun</FontFamily> <System:Double x:Key="CoreFontSize">16</System:Double> </ ResourceDictionary>
BaseStyle.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:BlendDemo.Styles"> <Style x:Key="TitleTextStyle" TargetType="{x:Type TextBlock}"> <Setter Property="FontFamily" Value="{DynamicResource TitleFontFamily}"/> <Setter Property="FontSize" Value="{DynamicResource TitleFontSize}"/> </Style > <Style x:Key="CoreTextStyle" TargetType="{x:Type TextBlock}"> <Setter Property="FontFamily" Value="{DynamicResource CoreFontFamily}"/> <Setter Property="FontSize" Value="{DynamicResource CoreFontSize}"/> </Style > <Style x:Key="CheckBoxBaseStyle" TargetType="{x:Type CheckBox}"> <Setter Property="FontFamily" Value="{DynamicResource CoreFontFamily}"/> <Setter Property="FontSize" Value="{DynamicResource CoreFontSize}"/> </Style > </ResourceDictionary>
7. 最后再进行一下标题部分的样式改进和抽取工作。在文档大纲面板中的人员列表TextBlock(如果在内部模板或样式的编辑状态,需要先退出)上右键单击,在弹出菜单中选择 分组-Border,可看到会在TextBlock外面套一层Border,并把Margin移到Border上。在Border上右键单击,选择 编辑样式-创建空样式,起名为TitleStyle。
此时进入Border的样式编辑状态。把Margin清除,可先转换为本地值,然后再重置。设置Padding为10,10,10,10,设置背景色为浅灰色。设置方法为,在选中画笔部分的Background属性后,点击中部的第二个按钮,设为实色画刷,然后选择或输入颜色,如下图所示。
效果如下,
代码如下,
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:BlendDemo" xmlns:System="clr-namespace:System;assembly=mscorlib" x:Class="BlendDemo.MainWindow" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525" d:DataContext="{d:DesignData /SampleData/SampleDataSource/SampleDataSource.xaml}"> <Window.Resources> <DataTemplate x:Key="PeopleListDataTemplate"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBlock Height="Auto" TextWrapping="Wrap" Text="{Binding Name}" Width="Auto" Style="{DynamicResource CoreTextStyle}"/> <CheckBox Content="男" Grid.Column="1" Height="Auto" Width="Auto" IsChecked="{Binding Sex}" Style="{DynamicResource CheckBoxBaseStyle}"/> </Grid> </DataTemplate> <Style x:Key="TitleStyle" TargetType="{x:Type Border }"> <Setter Property="Padding" Value="10"/> <Setter Property="Background" Value="#FFDEDDDD"/> </Style> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <Border Style="{DynamicResource TitleStyle}" > <TextBlock Text="人员列表" Style="{DynamicResource TitleTextStyle}"/> </Border> <ListBox Grid.Row="1" ItemsSource="{Binding Persons}" ItemTemplate="{DynamicResource PeopleListDataTemplate}" HorizontalContentAlignment="Stretch"/> </Grid> </Window>
需要将TitleStyle也放入BaseStyle.xaml中以便复用,就不演示了。