您能为一个 XAML 样式定义多个 TargetType 吗?

在 HTML/CSS 中,你可以定义一个可以应用于多种类型的元素的样式,例如:

.highlight {
color:red;
}

可同时适用于 P 和 DIV,例如:

<p class="highlight">this will be highlighted</p>
<div class="highlight">this will also be highlighted</div>

但是在 XAML 中,似乎必须为样式定义 TargetType,否则就会得到一个错误:

<Style x:Key="formRowLabel" TargetType="TextBlock">

有没有一种方法可以允许 XAML 样式应用于多个元素,甚至像 CSS 一样保持其开放?

57737 次浏览

在编译期间检查 WPF 样式中的 setter; 动态应用 CSS 样式。

您必须指定一个类型,以便 WPF 可以将 setter 中的属性解析为该类型的依赖项属性。

可以将目标类型设置为包含所需属性的基类,然后将该样式应用于派生类。例如,可以为 Control 对象创建样式,然后将其应用于多种类型的控件(Button、 TextBox、 CheckBox 等)

<Style x:Key="Highlight" TargetType="{x:Type Control}">
<Setter Property="Foreground" Value="Red"/>
</Style>

...

<Button Style="{StaticResource Highlight}" Content="Test"/>
<TextBox Style="{StaticResource Highlight}" Text="Test"/>
<CheckBox Style="{StaticResource Highlight}" Content="Test"/>

我把它修好了

<Style x:Key="HeaderStyleThin"  TargetType="{x:Type Border}">
<Setter Property="Background" Value="Black" />


<Style.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background=" Value="Red" />
</Style>
</Style.Resources>


</Style>

这个问题还有另一种答案。你可以把 TargetType 参数完全从样式中移除,这样它就可以应用到各种不同的控件,但是只有在属性名前加上“ Control”的前缀时才可以

<Style x:Key="Highlight">
<Setter Property="Control.Foreground" Value="Red"/>
</Style>

显然,这只适用于基控件类的属性。如果您尝试设置 ItemsSource say,它将失败,因为没有 Control。物品来源

<!-- Header text style -->
<Style x:Key="headerTextStyle">
<Setter Property="Label.VerticalAlignment" Value="Center"></Setter>
<Setter Property="Label.FontFamily" Value="Trebuchet MS"></Setter>
<Setter Property="Label.FontWeight" Value="Bold"></Setter>
<Setter Property="Label.FontSize" Value="18"></Setter>
<Setter Property="Label.Foreground" Value="#0066cc"></Setter>
</Style>


<!-- Label style -->
<Style x:Key="labelStyle" TargetType="{x:Type Label}">
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Margin" Value="0,0,0,5" />
</Style>

我认为这两种声明风格的方法都可以回答你的问题。 在第一个属性中,没有指定 TargetType,但是属性名称的前缀是“ Label”。在第二种方法中,为 Label 对象创建样式。

另一种方法是:

<UserControl.Resources>
<Style x:Key="commonStyle" TargetType="Control">
<Setter Property="FontSize" Value="24"/>
</Style>
<Style BasedOn="{StaticResource commonStyle}" TargetType="ListBox"/>
<Style BasedOn="{StaticResource commonStyle}" TargetType="ComboBox"/>
</UserControl.Resources>

我想对 Textblock 和 TextBox 应用一个样式,但是选择的答案对我来说不起作用,因为 Textblock 不是从 Control 继承的,在我的例子中,我想影响可见性属性,所以我使用了 FrameworkElement 框架元素

<Style x:Key="ShowIfRequiredStyle" TargetType="{x:Type FrameworkElement}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ShowIfRequiredStyle, UpdateSourceTrigger=PropertyChanged}" Value="true">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>


<TextBlock Style="{StaticResource ResourceKey=ShowIfRequiredStyle}"/>
<TextBox Style="{StaticResource ResourceKey=ShowIfRequiredStyle}"/>

这适用于 Visiability 属性,因为这两个项都从 Frameworkelement 继承,并且该属性在 Frameworkelement 中定义。当然,这不适用于仅在 Control 中定义的属性,你可以搜索层次结构树并尝试找到一个基类,无论如何,我认为这可以帮助某人,因为这是一个顶部搜索结果,所选择的答案有点不完整。