《Programming WPF》翻译 第6章 2.资源与样式
2015-11-13 17:59
330 查看
原文:《Programming WPF》翻译 第6章 2.资源与样式WPF的样式机制以来于资源体系来定位样式。正如你在第5章看到的,样式在元素的资源片段中定义,而且样式通过其名字被引用,正如示例6-18所示:
示例6-18
<Window x:Class="ResourcePlay.Window1" Text="ResourcePlay"
xmlns="http://schemas.microsoft.com/winfx/avalon/2005"
xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005">
<Window.Resources>
<Style x:Key="myStyle">
<Setter Property="Button.FontSize" Value="36" />
</Style>
</Window.Resources>
<Grid>
<Button Style="{StaticResource myStyle}">Hello</Button>
</Grid>
</Window>
然而,如何定义一个样式,使之自动的应用到一个元素,而无需显示指定要引用的资源——这是可以实现的,而且非常有用——当你需要把一个样式应用到具有独特类型的所有元素上,而不是把资源引用添加到每个元素上。示例6-19对示例6-18做了一些修改,展示了隐式声明这一功能。
示例6-19
<Window x:Class="ResourcePlay.Window1" Text="ResourcePlay"
xmlns="http://schemas.microsoft.com/winfx/avalon/2005"
xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005">
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Button.FontSize" Value="36" />
</Style>
</Window.Resources>
<Grid>
<Button>Hello</Button>
</Grid>
</Window>
注意到Button标签不再有其特定的Style属性。然而,这个样式仍然通过TargetType应用到Button上,而不是定义一个key,这个样式使用x:Type来设置TargetType,于是通知XAML为这个TargetType类提供一个System.Type对象。
如果FrameworkElement没有显示指定Style,它总是会寻找一个使用其自身类型的样式资源,作为其Target类型。
如果你建立了一些非样式的资源,例如SolidColorBrush,同时设置其x:Key为某个UI元素的类型,如果试着使用该元素的类型就会发生一个错误。这是因为你创建了一个带有TargetType的Style却没有指定x:Key,x:Key隐式地设置为同TargetType一样。这个Key用于定位style。因此,通常而言,你应该避免将x:Key设置为Type类型的对象。
因为元素会在资源中搜索它的样式,你可以利用系统级别的资源。你可以定义一个样式资源在局部范围内,如果你仅仅希望影响少量的元素;或者在一个广义范围上,例如Window.Resource;或者在应用程序的范围。而且样式可能延及到系统级别。这种样式和资源之间的联系是使用皮肤和主体的关键
6.2.1皮肤和主题
皮肤和主题都是控制UI外观的技术。主题,是一种系统级别的外观,例如Windows2000的经典外观,又如Windows XP的“Luna”主题。皮肤是一个特定于应用程序的外观,正如各种各样具有不同样式的媒体播放程序,例如WinApp和Windows Media Player
皮肤和主题都可以在WPF实现,作为一组资源应用于需要该样式的控件
既然皮肤的意图在于控制一个特定应用程序的外观,它将为标准控件提供更多的样式,可以在应用程序的指定部分定义各种各样有命名的资源。例如,音乐播放器可能使用一个ListBox用来显示歌曲列表。皮肤可以为之提供一个特定的外观而不用影响应用程序中其他的ListBox。因此应用程序可以为这个ListBox设置特定的命名的样式,同时要在这个样式中支持这个样式。对于这种特定情形,提供这样一个样式是可选择的,但是在其他情形中,应用程序需要皮肤提供提供指定的资源。例如,如果应用程序中有一个工具条,皮肤可能就需要提供资源并在其中为这个工具条定义图像。
同样,主体是用于所有应用程序,因此,其必须为所有类型的控件提供模板和样式。比较而言,一个皮肤是特定于应用程序的,所以它不必提供广泛全面的一组样式。如果应用程序并不使用每一个单独的控件类型,皮肤只需要为那些在应用程序中出现的控件提供样式。示例6-20和示例6-21为一个相当简单的皮肤,展示了xaml和相应的后台代码
示例6-20
<ResourceDictionary x:Class="SimpleSkin.BlueSkin"
xmlns="http://schemas.microsoft.com/winfx/avalon/2005"
xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005"
>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Blue" />
<Setter Property="Foreground" Value="White" />
</Style>
</ResourceDictionary>
示例6-21
using System;
using System.Windows;
<Window x:Class="SimpleSkin.Window1" Text="SimpleSkin"
xmlns="http://schemas.microsoft.com/winfx/avalon/2005"
xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005">
<Grid Margin="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<RadioButtonList x:Name="radioSkins">
<TextBlock>Green</TextBlock>
<TextBlock>Blue</TextBlock>
</RadioButtonList>
<Button Grid.Row="1">Hello</Button>
</Grid>
</Window>
示例[b]6-23
using System;
using System.Windows;
using System.Windows.Controls;
ResourceDictionary skinResources = new FooSkinResources( );
ResourceDictionary nonSkinAppResources = new DrawingResources( );
foreach (DictionaryEntry de in nonSkinAppResources) {
skinResources.Add(de.Key, de.Value);
}
如上,你可以将代码添加到加载资源的方法中。在示例6-23中,你可以在EnsureSkins方法中和并资源,将blue和green皮肤都和并到nonSkinAppResources中。
示例6-18
<Window x:Class="ResourcePlay.Window1" Text="ResourcePlay"
xmlns="http://schemas.microsoft.com/winfx/avalon/2005"
xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005">
<Window.Resources>
<Style x:Key="myStyle">
<Setter Property="Button.FontSize" Value="36" />
</Style>
</Window.Resources>
<Grid>
<Button Style="{StaticResource myStyle}">Hello</Button>
</Grid>
</Window>
然而,如何定义一个样式,使之自动的应用到一个元素,而无需显示指定要引用的资源——这是可以实现的,而且非常有用——当你需要把一个样式应用到具有独特类型的所有元素上,而不是把资源引用添加到每个元素上。示例6-19对示例6-18做了一些修改,展示了隐式声明这一功能。
示例6-19
<Window x:Class="ResourcePlay.Window1" Text="ResourcePlay"
xmlns="http://schemas.microsoft.com/winfx/avalon/2005"
xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005">
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Button.FontSize" Value="36" />
</Style>
</Window.Resources>
<Grid>
<Button>Hello</Button>
</Grid>
</Window>
注意到Button标签不再有其特定的Style属性。然而,这个样式仍然通过TargetType应用到Button上,而不是定义一个key,这个样式使用x:Type来设置TargetType,于是通知XAML为这个TargetType类提供一个System.Type对象。
如果FrameworkElement没有显示指定Style,它总是会寻找一个使用其自身类型的样式资源,作为其Target类型。
如果你建立了一些非样式的资源,例如SolidColorBrush,同时设置其x:Key为某个UI元素的类型,如果试着使用该元素的类型就会发生一个错误。这是因为你创建了一个带有TargetType的Style却没有指定x:Key,x:Key隐式地设置为同TargetType一样。这个Key用于定位style。因此,通常而言,你应该避免将x:Key设置为Type类型的对象。
因为元素会在资源中搜索它的样式,你可以利用系统级别的资源。你可以定义一个样式资源在局部范围内,如果你仅仅希望影响少量的元素;或者在一个广义范围上,例如Window.Resource;或者在应用程序的范围。而且样式可能延及到系统级别。这种样式和资源之间的联系是使用皮肤和主体的关键
6.2.1皮肤和主题
皮肤和主题都是控制UI外观的技术。主题,是一种系统级别的外观,例如Windows2000的经典外观,又如Windows XP的“Luna”主题。皮肤是一个特定于应用程序的外观,正如各种各样具有不同样式的媒体播放程序,例如WinApp和Windows Media Player
皮肤和主题都可以在WPF实现,作为一组资源应用于需要该样式的控件
既然皮肤的意图在于控制一个特定应用程序的外观,它将为标准控件提供更多的样式,可以在应用程序的指定部分定义各种各样有命名的资源。例如,音乐播放器可能使用一个ListBox用来显示歌曲列表。皮肤可以为之提供一个特定的外观而不用影响应用程序中其他的ListBox。因此应用程序可以为这个ListBox设置特定的命名的样式,同时要在这个样式中支持这个样式。对于这种特定情形,提供这样一个样式是可选择的,但是在其他情形中,应用程序需要皮肤提供提供指定的资源。例如,如果应用程序中有一个工具条,皮肤可能就需要提供资源并在其中为这个工具条定义图像。
同样,主体是用于所有应用程序,因此,其必须为所有类型的控件提供模板和样式。比较而言,一个皮肤是特定于应用程序的,所以它不必提供广泛全面的一组样式。如果应用程序并不使用每一个单独的控件类型,皮肤只需要为那些在应用程序中出现的控件提供样式。示例6-20和示例6-21为一个相当简单的皮肤,展示了xaml和相应的后台代码
示例6-20
<ResourceDictionary x:Class="SimpleSkin.BlueSkin"
xmlns="http://schemas.microsoft.com/winfx/avalon/2005"
xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005"
>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Blue" />
<Setter Property="Foreground" Value="White" />
</Style>
</ResourceDictionary>
示例6-21
using System;
using System.Windows;
<Window x:Class="SimpleSkin.Window1" Text="SimpleSkin"
xmlns="http://schemas.microsoft.com/winfx/avalon/2005"
xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005">
<Grid Margin="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<RadioButtonList x:Name="radioSkins">
<TextBlock>Green</TextBlock>
<TextBlock>Blue</TextBlock>
</RadioButtonList>
<Button Grid.Row="1">Hello</Button>
</Grid>
</Window>
示例[b]6-23
using System;
using System.Windows;
using System.Windows.Controls;
ResourceDictionary skinResources = new FooSkinResources( );
ResourceDictionary nonSkinAppResources = new DrawingResources( );
foreach (DictionaryEntry de in nonSkinAppResources) {
skinResources.Add(de.Key, de.Value);
}
如上,你可以将代码添加到加载资源的方法中。在示例6-23中,你可以在EnsureSkins方法中和并资源,将blue和green皮肤都和并到nonSkinAppResources中。
相关文章推荐
- 《Programming WPF》翻译 第5章 5.数据模板和样式
- 《Programming WPF》翻译 第5章 4.元素类型样式
- 《Programming WPF》翻译 第5章 2.内嵌样式
- 《Programming WPF》翻译 第5章 1.不使用样式
- CSS侧边栏,ng-click定义选中事件
- WPF笔记(1.9 样式和控件模板)——Hello,WPF!
- 8.1.5 CSS3文字(2)( 字体 )
- CSS 伪类与伪元素
- css代码之所以初始化
- css3中font-face属性的用法详解
- css文件如何注释
- CSS选择器
- 【04】 CSS开发注意事项
- 动态加载js,css
- 一句命令快速合并 JS、CSS
- 一句命令快速合并 JS、CSS
- CSS学习<1>
- css float属性
- 使用CSS3 will-change提高页面滚动、动画等渲染性能
- 关于网页设计的css+html相对定位和决定定位的理解