您的位置:首页 > Web前端 > CSS

《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中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: