如何将样式基于资源字典中的另一种样式?

时间:2011-04-15 09:47:38

标签: wpf xaml styles

我有一个主题应用于资源字典中的所有按钮。现在我想在继承字典中的样式更改时向按钮添加触发器。我尝试了以下代码,但它说无法找到控件。我该如何解决?

<UserControl.Resources>
  <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
          <ResourceDictionary Source="Theme.xaml"/>
      </ResourceDictionary.MergedDictionaries>

      <conv:ErrorContentConverter x:Key="ErrorContentConverter" />

      <Style x:Key="ValidTrigger" 
             TargetType="Control" BasedOn="{StaticResource {x:Type Control}}">
         <Style.Triggers>
            <DataTrigger Binding="{Binding Path=IsValid}" Value="False">
              <Setter Property="IsEnabled" Value="false" />
            </DataTrigger>
         </Style.Triggers>
      </Style>   
  </ResourceDictionary>
</UserControl.Resources>

基本模板:

    <Style TargetType="{x:Type Button}" BasedOn="{x:Null}">
    <Setter Property="FocusVisualStyle" 
            Value="{DynamicResource NuclearButtonFocusVisual}" />
    <Setter Property="Foreground" Value="#FF042271" />
    <Setter Property="FontFamily" Value="Trebuchet MS" />
    <Setter Property="FontSize" Value="12" />
    <Setter Property="Padding" Value="3" />

    <Setter Property="Template" Value="{DynamicResource ButtonTemplate}" />
</Style>

4 个答案:

答案 0 :(得分:22)

我过去曾使用的一个技巧:在为您的应用定义毛毯样式的ResourceDictionary中,为您要继承的样式添加x:Key,如下所示: / p>

<Style TargetType="{x:Type Button}" x:Key="ButtonStyle">
  <!-- your style here -->
</Style>

要将此样式应用于指定类型的所有控件(在此示例中为Button),而不必显式设置每个Style的{​​{1}}属性,请添加另一个样式{{ 1}}这种风格,但没有钥匙:

Button

使用此方法,应用中的所有BasedOn都会自动继承您的自定义样式,但您仍然可以创建其他样式<Style TargetType="{x:Type Button}" BasedOn="{StaticResource ButtonStyle}" /> Button条目,并避免将所有内容都吹走定制造型。

答案 1 :(得分:18)

为你的基础风格命名,比如说FooStyle。

在您给出的示例中,修改TargetType和BasedOn,如下所示:

 <Style x:Key="ValidTrigger" 
        TargetType="{x:Type Control}" BasedOn="{StaticResource {x:Type Control}}" >
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=IsValid}" Value="False">
            <Setter Property="IsEnabled" Value="false" />
        </DataTrigger>
    </Style.Triggers>
</Style>

答案 2 :(得分:1)

我认为没有为“控制”定义基本样式所以你的 BasedOn="{StaticResource {x:Type Control}}"部分找不到任何内容。

您可能想要更改

<Style x:Key="ValidTrigger" TargetType="Control" BasedOn="{StaticResource {x:Type Control}}" >

<Style x:Key="ValidTrigger" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}" >

答案 3 :(得分:0)

StaticResource vs DynamicResource

您想使用 DynamicResource 而不是StaticResource。您的应用程序将编译,资源将在运行时而不是编译时解析。过去,在旧的WPF时代,DynamicResource会有更多的性能成本,但现在似乎不是问题。我的意思是,哎呀,Expression Blend是用WPF编写的,并且全面使用DynamicResources。


P.S。请记住,如果您实际上没有定义资源名称,您的应用程序仍将运行,但在您的情况下,您将缺少功能。 :)