-
WPF样式:

使用WPF样式

在前一章,我们介绍了样式的概念,我们使用了本地定义样式的一个基础示例,它针对特定类型的控件 - TextBlock。 但是,样式可以在几个不同的范围中定义,具体取决于您希望在何处以及如何使用它们,甚至可以将样式限制为仅在您明确需要的控件上使用。 在本章中,我将向您展示定义样式的所有不同方式。

本地控件的特定样式

您可以直接在控件上定义样式,如下所示:

<Window x:Class="WpfTutorialSamples.Styles.ControlSpecificStyleSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ControlSpecificStyleSample" Height="100" Width="300">
    <Grid Margin="10">
        <TextBlock Text="Style test">
            <TextBlock.Style>
                <Style>
                    <Setter Property="TextBlock.FontSize" Value="36" />
                </Style>
            </TextBlock.Style>
        </TextBlock>
    </Grid>
</Window>

在本例中,样式只影响这个特定的TextBlock控件,所以为什么要这么麻烦? 嗯,在这种情况下,根本没有任何意义。 我可以用TextBlock控件上的单个FontSize属性替换所有额外的标记,但正如我们稍后将看到的,样式可以做的不仅仅是设置属性,例如样式触发器可以使上述示例在实际应用程序中很有用。但是,您定义的大多数样式可能会在更高的范围。

本地子控件样式

使用控件的Resources部分,可以面向此控件的子控件(以及这些子控件的子控件等)。 这基本上就是我们在上一章的介绍示例中所做的,它看起来像这样:

<Window x:Class="WpfTutorialSamples.Styles.SimpleStyleSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SimpleStyleSample" Height="200" Width="250">
    <StackPanel Margin="10">
        <StackPanel.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="Foreground" Value="Gray" />
                <Setter Property="FontSize" Value="24" />
            </Style>
        </StackPanel.Resources>
        <TextBlock>Header 1</TextBlock>
        <TextBlock>Header 2</TextBlock>
        <TextBlock Foreground="Blue">Header 3</TextBlock>
    </StackPanel>
</Window>

这对于更多本地样式需求非常有用。 例如在对话框中执行此操作非常有意义,您只需要一组控件看起来相同,而不是在每个控件上设置各个属性。

窗口范围的样式

范围层次结构中的下一步是定义Window资源中的样式。 这与StackPanel的完全相同,但是在您希望将特定样式应用于窗口中的所有控件(或者UserControl)的情况下,它非常有用,而不仅仅是在特定控件本地中。 这是一个修改过的例子:

<Window x:Class="WpfTutorialSamples.Styles.WindowWideStyleSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WindowWideStyleSample" Height="200" Width="300">
    <Window.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="Foreground" Value="Gray" />
            <Setter Property="FontSize" Value="24" />
        </Style>
    </Window.Resources>
    <StackPanel Margin="10">
        <TextBlock>Header 1</TextBlock>
        <TextBlock>Header 2</TextBlock>
        <TextBlock Foreground="Blue">Header 3</TextBlock>
    </StackPanel>
</Window>

正如您所看到的,结果完全相同,但它确实意味着您可以在窗口中的任何位置放置控件,并且样式仍然适用。

应用程序范围的样式

如果您希望在不同的窗口中使用整个应用程序统一的样式,则可以为整个应用程序定义它。 这是在Visual Studio为您创建的App.xaml文件中完成的,并且就像在窗口范围的示例中一样:

App.xaml

<Application x:Class="WpfTutorialSamples.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	 StartupUri="Styles/WindowWideStyleSample.xaml">
    <Application.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="Foreground" Value="Gray" />
            <Setter Property="FontSize" Value="24" />
        </Style>
    </Application.Resources>
</Application>

Window

<Window x:Class="WpfTutorialSamples.Styles.WindowWideStyleSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ApplicationWideStyleSample" Height="200" Width="300">
    <StackPanel Margin="10">
        <TextBlock>Header 1</TextBlock>
        <TextBlock>Header 2</TextBlock>
        <TextBlock Foreground="Blue">Header 3</TextBlock>
    </StackPanel>
</Window>

明确使用样式

您可以很好地控制如何以及在何处将样式应用于控件,从本地样式到应用程序范围的样式,可以帮助您在整个应用程序中获得一致的外观,但到目前为止,我们所有的样式都针对特定的控件类型,然后所有这些控件都使用了它。 但并非必须如此。

通过在样式上设置x:Key属性,告诉WPF,只有您在特定控件上显式引用它时,才使用此样式。 让我们尝试一下这种情况的例子:

<Window x:Class="WpfTutorialSamples.Styles.ExplicitStyleSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExplicitStyleSample" Height="150" Width="300">
    <Window.Resources>
        <Style x:Key="HeaderStyle" TargetType="TextBlock">
            <Setter Property="Foreground" Value="Gray" />
            <Setter Property="FontSize" Value="24" />
        </Style>
    </Window.Resources>
    <StackPanel Margin="10">
        <TextBlock>Header 1</TextBlock>
        <TextBlock Style="{StaticResource HeaderStyle}">Header 2</TextBlock>
        <TextBlock>Header 3</TextBlock>
    </StackPanel>
</Window>

请注意,即使TargetType设置为TextBlock,并且为整个窗口定义了样式,但只有中间的TextBlock(我明确引用HeaderStyle样式)才使用该样式。 这允许您定义以特定控件类型为目标的样式,但仅在需要它的位置使用它。

小结

WPF样式允许您轻松地在整个应用程序中重复使用某些外观。 使用x:Key属性,您可以决定是否显式引用样式才能生效,或者它是否应该以所有控件为目标。