wpf 您能否为一种 XAML 样式定义多个 TargetType?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/802658/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:18:54  来源:igfitidea点击:

Can you define multiple TargetTypes for one XAML style?

wpfxamlstyles

提问by Edward Tanguay

In HTML/CSS you can define a style which can be applied to many types of elements, e.g.:

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

.highlight {
    color:red;
}

can be applied to both P and DIV, e.g.:

可以应用于 P 和 DIV,例如:

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

but in XAML you seem to have to define the TargetType for styles, otherwise you get an error:

但在 XAML 中,您似乎必须为样式定义 TargetType,否则会出现错误:

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

is there a way to allow a XAML style to be applied to multiple elements or even to leave it open as in CSS?

有没有办法允许 XAML 样式应用于多个元素,甚至像在 CSS 中一样保持打开状态?

回答by Josh G

The setters in WPF styles are checked during compile time; CSS styles are applied dynamically.

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

You have to specify a type so that WPF can resolve the properties in the setters to the dependency properties of that type.

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

You can set the target type to base classes that contain the properties you want and then apply that style to derived classes. For example, you could create a style for Control objects and then apply it to multiple types of controls (Button, TextBox, CheckBox, etc)

您可以将目标类型设置为包含所需属性的基类,然后将该样式应用于派生类。例如,您可以为 Control 对象创建一个样式,然后将其应用于多种类型的控件(按钮、文本框、复选框等)

<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"/>

回答by Gaurang

<!-- 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>

I think both of these methods of declaring a style might answer your question. In the first one, there is no TargetType specified, but the property names are prefixed with 'Label'. In the second one, the style is created for Label objects.

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

Another method to do it is:

另一种方法是:

<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>

回答by The One

I wanted to apply a style to a Textblock and a TextBox but the selected answer didn't work for me because Textblock doesn't inherit from Control, in my case I wanted to affect the Visibility property, so I used FrameworkElement

我想将样式应用于 Textblock 和 TextBox,但所选答案对我不起作用,因为 Textblock 不继承自 Control,在我的情况下,我想影响 Visibility 属性,所以我使用了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}"/>

This works for the Visibility property because both items inherit from Frameworkelement and the property is defined there. Of course this will not work for properties defined only in Control, you can search the hierarchy tree and try to find a base class, anyway I thought this could help someone since this is a top search result and the selected answer is a little incomplete.

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

回答by PaulMolloy

There is an alternative answer to the question. You CAN leave the TargetType parameter off the style altogether which will allow it to apply to various different controls, but only if you prefix the property name with "Control."

这个问题有一个替代答案。您可以将 TargetType 参数完全保留在样式之外,这将允许它应用于各种不同的控件,但前提是您在属性名称前加上“Control”。

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

Obviously, this only works for properties of the base control class. If you tried to set ItemsSource say, it would fail because there is no Control.ItemsSource

显然,这仅适用于基本控件类的属性。如果你试图设置 ItemsSource 说,它会失败,因为没有 Control.ItemsSource

回答by Avlin

I got this working

我得到了这个工作

<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>