首页 > 代码库 > Blend 2015 教程 (二) 样式

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.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>

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中以便复用,就不演示了。

下一篇将进一步修改ListBox的样式,敬请关注。

Blend 2015 教程 (二) 样式