WPF:如何像CSS一样为类添加样式?

19

假设我有一个包含4个边框的UserControl:

<Border />
<Border />
<Border />
<Border />

现在我可以在我的资源中进行:

<Style TargetType="{x:Type Border}">
  ... change some properties here
</Style>

现在这一切都很好,但是它将会针对我用户控件中的所有边框。 但是如果我只想针对其中的一部分怎么办?

我想要:

<Border Class="Type1" />
<Border Class="Type1" />
<Border />
<Border />

然后继续:

<Style TargetType="{x:Type Border}" TargetClass="Type1">
  ... change some properties here
</Style>

但是显然这个不存在,有没有其他方法可以实现我想要的?谢谢

4个回答

22

尽管语法不如CSS那么简洁,但它更加具体。

基于你的例子,你要找的是:

<Border Style="{StaticResource Type1}" />
<Border Style="{StaticResource Type1}" />
<Border />
<Border />

然后执行:

<Style TargetType="{x:Type Border}" x:Key="Type1">
  ... change some properties here
</Style>

请记住,WPF样式实际上不像CSS那样级联。

更详细的样式参考:https://web.archive.org/web/20141210000517/http://dotnetslackers.com/articles/wpf/StylesResourcesAndControlTemplatesInWPF.aspx


链接已经失效。 - ToolmakerSteve
3
互联网档案馆来拯救了! - Matt DeKrey

10

我发现大多数人不知道的是WPF可以在Style.Resources中嵌套样式。例如:

<!-- Define a new style for Borders called InfoBox, that will have a red background, 
     and further override all buttons within it to have Yellow Text.  An extra style,
     "Strawberry" is also defined, that lets specific buttons be selected to be styled
     as Green FG on DarkRed BG -->
<Style TargetType="{x:Type Border}" x:Key="InfoBox">
  <Setter Property="Background" Value="Red"/>
  <Style.Resources>
    <Style TargetType="{x:Type Button}">
      <Setter Property="Foreground" Value="DarkYellow"/>
    </Style>
    <Style TargetType="{x:Type Button}" x:Key="Strawberry">
      <Setter Property="Foreground" Value="Green"/>
      <Setter Property="Background" Value="DarkRed"/>
    </Style>
  </Style.Resources>
</Style>

...

<Border Style="{DynamicResource InfoBox}">
   <StackPanel>
     <Button Content="I am a banana!"/>
     <Button Style="{DynamicResource Strawberry}" Content="I am red!"/>
   </StackPanel>
</Border>

虽然它不完全与CSS相同(标准伪选择器的支持不多),但它为你提供了巨大的能力和灵活性。如果能熟练使用ItemsControls,那么你可以做出一些很棒的东西。


Style.Resources 字典中的默认样式似乎无法解析。 - codekaizen
在WPF中,看起来在VS设计器中可以工作,但会出现警告“无法解析资源“Strawberry””。一旦我取消嵌套Strawberry,警告就消失了。必须使用DynamicResource。静态资源将抛出未解决的错误。 - Jeson Martajaya

2

您可以使用x:key和Border的StaticResource(或DynamicResource)属性直接在<Border>上设置样式。如果您希望在运行时更改样式,则应优先使用DynamicResource而不是StaticResource。

<Style x:Key="something" TargetType="{x:Type Border}">
</Style>

<Border style="{StaticResource something}"/>

2
<Style x:Key="styleKey" TargetType="{x:Type Border}">
  ... change some properties here
</Style>

and

<Border Style="{StaticResource styleKey}"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接