样式中的代码可重用性

时间:2015-01-09 21:42:46

标签: wpf xaml triggers

我有一个样式元素,它有很少的编辑,大多数都是重复的。我如何使它更通用 - 因此基于值而不是重复代码两次设置setter属性

<ResourceDictionary>
<Style x:Key="TextBlockStyleEnvironment" TargetType="{x:Type TextBlock}">
    <Setter Property="Margin" Value="5,4,0,0" />
    <Setter Property="FontSize" Value="8" />
    <Setter Property="HorizontalAlignment" Value="Stretch" />
    <Setter Property="VerticalAlignment" Value="Stretch" />
    <Setter Property="FontWeight" Value="Bold" />
</Style>
<Style x:Key="TextBlockStyleLocation" TargetType="{x:Type TextBlock}">
    <Setter Property="Margin" Value="5,4,0,0" />
    <Setter Property="FontSize" Value="10" />
    <Setter Property="HorizontalAlignment" Value="Stretch" />
    <Setter Property="VerticalAlignment" Value="Stretch" />
    <Setter Property="FontWeight" Value="Bold" />
</Style>
</ResourceDictionary>

从代码中可以看出,除了Margin和FontSize之外,所有setter属性都是相同的。还附上了渲染的截图。

enter image description here

请注意 - 希望将此自包含在样式中,并且在消费时不要在XAML中在本地级别声明。

Env的可能值可以是Dev,QA,Prod,可能的位置值可以是TK,LN

按照以下方式在XAML代码段中使用:

<Grid DataContext="{....}">
   <StackPanel>
     <TextBlock Text="{Binding Environment}" Style="{StaticResource TextBlockStyleEnvironment}"/>
     <TextBlock Text="{Binding Location}" Style="{StaticResource TextBlockStyleLocation}"/>

2 个答案:

答案 0 :(得分:3)

您可以使用样式继承:

<ResourceDictionary>
  <Style x:Key="BaseTextBlockStyle" TargetType="{x:Type TextBlock}">
      <Setter Property="Margin" Value="5,4,0,0" />
      <Setter Property="FontSize" Value="8" />
      <Setter Property="HorizontalAlignment" Value="Stretch" />
      <Setter Property="VerticalAlignment" Value="Stretch" />
      <Setter Property="FontWeight" Value="Bold" />
  </Style>

  <Style x:Key="TextBlockStyleEnvironment" BasedOn="{StaticResource BaseTextBlockStyle}" TargetType="{x:Type TextBlock}" />

  <Style x:Key="TextBlockStyleLocation" BasedOn="{StaticResource BaseTextBlockStyle}" TargetType="{x:Type TextBlock}">
      <Setter Property="FontSize" Value="10" />
  </Style>
</ResourceDictionary>

此外,您可以创建附加属性并绑定到控件模板中的属性。这使您可以灵活地不必创建数百种样式,因为某些时间需要不同。

一个很好的例子是一个带图像的按钮。当鼠标悬停在图像上时,图像需要更改。通常,您必须为实现该行为的每个按钮创建新的控件模板/样式。但是,如果创建两个附加属性 - NormalStateImageSource和MosueOverImageSource,则可以绑定到控件模板中的属性。这允许您为按钮设置一个完整的样式,稍后为其他按钮声明单独的样式,只更改这些附加属性的值。

答案 1 :(得分:0)

WPF世界中的技术很少。

首先,如果样式属于同一类型,则可以使用BasedOn属性:

<Style x:Key="GenericTextBlockStyle" TargetType="{x:Type TextBlock}">
    <Setter Property="Margin" Value="5,4,0,0" />
    <Setter Property="FontSize" Value="8" />
</Style>

<Style x:Key="TextBlockStyleEnvironment" 
        BasedOn="{StaticResource GenericTextBlockStyle}"
        TargetType="{x:Type TextBlock}">

</Style>

然而BasedOn属性有时会变得非常混乱。它也可以这样做,这将适用于不同类型的元素:

<Thickness x:Key="LeftBorderMargin" Top="10" />

<Style x:Key="TextBlockStyleEnvironment" TargetType="{x:Type TextBlock}">
    <Setter Property="Margin" Value="{StaticResource LeftBorderMargin}" />
</Style>

通常的做法是重构Style元素中的所有颜色/边距,以实现可重用性。