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。

这时美工板导航栏变为如下图,

Image(14)

表示正在编辑ListBox控件的模板中的TextBlock的样式,这个需要理解。

在属性面板中把字体改为SimSun,字号改为16 px,再把字体和字号转换为新资源,起名为CoreFontFamily和CoreFontSize。

4. 点击文档大纲面板的返回上一层按钮,然后选择CheckBox控件,为其创建新样式,起名为CheckBoxBaseStyle,此时需要点击主菜单 格式-编辑样式-创建空白项,名称改为CheckBoxBaseStyle,点击确定。在属性面板中点击字体的小方块,选择 本地资源-CoreFontFamily,点击字号的小方块,选择 本地资源-CoreFontSize。

5. 至此字体字号的抽取工作已经基本完成,也可针对前景色进行抽取。

设计器呈现效果如下,

Image(15)

代码如下,

<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,现在样式和资源都在本文件中,没有直接放入他们该在的地方。下面使用资源面板对资源进行一下重新组织。目前资源面板如下图,

Image(16)

将TextBlockStyle1删除(点击右键,在弹出菜单中选择删除),将DataTemplate1重命名为PeopleListBoxDataTemplate,重命名的方法是,在选中该资源的条件下,在资源名称上左键单击,此时变为编辑状态,可修改或粘贴,焦点离开时会弹出如下所示对话框,

Image(17)

问是否更新引用,选择更新引用,点击继续完成修改。

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属性后,点击中部的第二个按钮,设为实色画刷,然后选择或输入颜色,如下图所示。

Image(18)

效果如下,

Image(19)

代码如下,

<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的样式,敬请关注。

posted @ 2014-12-27 16:06  ClockDotNet  阅读(11211)  评论(2编辑  收藏  举报