【WPF.NET开发】创建样式

2023-12-22 10:24:01

本文内容

  1. 创建样式
  2. 隐式应用样式
  3. 显式应用样式
  4. 以编程方式应用样式
  5. 扩展样式
  6. TargetType 属性与 x:Key 属性之间的关系

使用 Windows Presentation Foundation (WPF),可以使用自己的可重用样式自定义现有控件的外观。 可以对应用、窗口和页面全局应用样式,也可以将样式直接应用于控件。

1、创建样式

可以将?Style?视为一种将一组属性值应用到一个或多个元素的便利方法。 可以对从?FrameworkElement?或?FrameworkContentElement(如?Window?或?Button)派生的任何元素使用样式。

声明样式的最常见方法是在 XAML 文件的?Resources?部分中声明为资源。 由于样式是一种资源,因此它们同样遵从适用于所有资源的范围规则。 简而言之,声明样式的位置会影响样式的应用范围。 例如,如果在应用定义 XAML 文件的根元素中声明样式,则该样式可以在应用中的任何位置使用。

<Application x:Class="IntroToStylingAndTemplating.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:IntroToStylingAndTemplating"
             StartupUri="WindowExplicitStyle.xaml">
    <Application.Resources>
        <ResourceDictionary>
            
            <Style x:Key="Header1" TargetType="TextBlock">
                <Setter Property="FontSize" Value="15" />
                <Setter Property="FontWeight" Value="ExtraBold" />
            </Style>
            
        </ResourceDictionary>
    </Application.Resources>
</Application>

如果在应用的一个 XAML 文件中声明样式,则该样式只能在该 XAML 文件中使用。?

<Window x:Class="IntroToStylingAndTemplating.WindowSingleResource"
        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:IntroToStylingAndTemplating"
        mc:Ignorable="d"
        Title="WindowSingleResource" Height="450" Width="800">
    <Window.Resources>
        
        <Style x:Key="Header1" TargetType="TextBlock">
            <Setter Property="FontSize" Value="15" />
            <Setter Property="FontWeight" Value="ExtraBold" />
        </Style>
        
    </Window.Resources>
    <Grid />
</Window>

样式由?<Setter>?子元素组成,这些元素在应用了样式的元素上设置属性。 在上面的示例中,请注意,样式已设置为通过?TargetType?属性应用于?TextBlock?类型。 样式会将?FontSize?设置为?15,并将?FontWeight?设置为?ExtraBold。 为样式更改的每个属性添加一个?<Setter>

2、隐式应用样式

Style?是一种将一组属性值应用到多个元素的便利方法。 例如,请考虑以下?TextBlock?元素及其在窗口中的默认外观。

<StackPanel>
    <TextBlock>My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

stylingintro-textblocksbefore.png?view=netdesktop-8.0

可以通过直接对每个?TextBlock?元素设置属性(如?FontSize?和?FontFamily)来更改默认外观。 但是,如果需要让?TextBlock?元素共享某些属性,可以在 XAML 文件的?Resources?部分中创建?Style,如下所示。

<Window.Resources>
    <!--A Style that affects all TextBlocks-->
    <Style TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

将样式的?TargetType?设置为?TextBlock?类型并省略?x:Key?属性时,该样式将应用到样式的所有?TextBlock?元素,通常是 XAML 文件本身。

现在?TextBlock?元素如下所示。

stylingintro-textblocksbasestyle.png?view=netdesktop-8.0

3、显式应用样式

如果向样式添加具有值的?x:Key?属性,则样式将不再隐式应用于?TargetType?的所有元素。 只有显式引用样式的元素才会应用样式。

下面是上一节中的样式,但使用?x:Key?属性进行了声明。

<Window.Resources>
    <Style x:Key="TitleText" TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

若要应用样式,请使用?StaticResource 标记扩展将元素上的?Style?属性设置为?x:Key?值,如下所示。

<StackPanel>
    <TextBlock Style="{StaticResource TitleText}">My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

请注意,第一个?TextBlock?元素已应用样式,而第二个 TextBlock 元素保持不变。 上一节中的隐式样式已更改为声明了?x:Key?属性的样式,也就是说,该样式影响的唯一元素是直接引用该样式的那个元素。

create-a-style-explicit-textblock.png?view=netdesktop-8.0

在显式或隐式应用样式后,它将变为密封状态,不能更改。 如果要更改已应用的样式,请创建新的样式来替换现有样式。?可以创建一个根据自定义逻辑选择要应用的样式的对象。?

4、以编程方式应用样式

若要以编程方式将已命名的样式分配到元素,请从资源集合中获取样式,并将其分配到元素的?Style?属性。 资源集合中的项属于?Object?类型。 因此,在将检索到的样式分配给?Style?属性之前,必须将它强制转换为?System.Windows.Style。 例如,下面的代码将名为?textblock1?的?TextBlock?的样式设置为定义的样式?TitleText

textblock1.Style = (Style)Resources["TitleText"];

5、扩展样式

也许你希望两个?TextBlock?元素共享某些属性值,如?FontFamily?和居中的?HorizontalAlignment。 你可能还希望文本“My Pictures”?具有一些其他属性。 可以通过创建基于第一个样式的新样式来实现此目的,如下所示。

<Window.Resources>
    <!-- .... other resources .... -->

    <!--A Style that affects all TextBlocks-->
    <Style TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
    
    <!--A Style that extends the previous TextBlock Style with an x:Key of TitleText-->
    <Style BasedOn="{StaticResource {x:Type TextBlock}}"
           TargetType="TextBlock"
           x:Key="TitleText">
        <Setter Property="FontSize" Value="26"/>
        <Setter Property="Foreground">
            <Setter.Value>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Offset="0.0" Color="#90DDDD" />
                        <GradientStop Offset="1.0" Color="#5BFFFF" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<StackPanel>
    <TextBlock Style="{StaticResource TitleText}" Name="textblock1">My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

此?TextBlock?样式现在居中,使用大小为?26?的?Comic Sans MS?字体,并将前景色设置为如示例中显示的?LinearGradientBrush。 请注意,它会重写基本样式的?FontSize?值。 如果有多个?Setter?指向?Style?中的同一属性,则最后声明的?Setter?优先。

TextBlock?元素现在如下所示:

stylingintro-textblocks.png?view=netdesktop-8.0

此?TitleText?样式扩展为?TextBlock?类型创建的样式,该样式由?BasedOn="{StaticResource {x:Type TextBlock}}"?引用。 还可以使用样式的?x:Key?扩展具有?x:Key?的样式。 例如,如果有一个名为?Header1?的样式,并且你需要扩展该样式,可以使用?BasedOn="{StaticResource Header1}"

6、TargetType 属性与 x:Key 属性之间的关系

如前所述,将?TargetType?属性设置为?TextBlock?时,如果不为样式分配?x:Key,会导致将样式应用于所有?TextBlock?元素。 在此情况下,x:Key?隐式设置为?{x:Type TextBlock}。 这意味着,如果将?x:Key?值显式设置为除?{x:Type TextBlock}?以外的任何值,则?Style?不会自动应用于所有?TextBlock?元素。 相反,必须将该样式(通过使用?x:Key?值)显式应用到?TextBlock?元素。 如果你的样式位于资源部分中,并且你未对样式设置?TargetType?属性,则必须设置?x:Key?属性。

除了为?x:Key?提供默认值以外,TargetType?属性还指定 setter 属性应用到的类型。 如果不指定?TargetType,则必须使用语法?Property="ClassName.Property",通过类名称限定?Setter?对象中的属性。 例如,必须将?Property?设置为?"TextBlock.FontSize"?或?"Control.FontSize",而不是设置?Property="FontSize"

另请注意,许多 WPF 控件由其他 WPF 控件的组合构成。 如果创建应用于某个类型的所有控件的样式,可能会产生意外结果。 例如,如果创建一个样式,该样式以?Window中的?TextBlock?类型为目标,那么,即使?TextBlock?是另一个控件(如?ListBox)的一部分,该样式也将应用于窗口中的所有?TextBlock?控件。

文章来源:https://blog.csdn.net/m0_51887793/article/details/135115552
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。