How to base a style on another style in a resource dictionary?

27,727

Solution 1

Give your base Style a name, say FooStyle.

In the example you gave, modify the TargetType and BasedOn to look as follows:

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

Solution 2

One trick I've used in the past: in your ResourceDictionary that defines blanket styles for your application, add an x:Key to the style you'd like to inherit from, like so:

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

To apply this style to all controls of the specified type (Button in this example) without having to explicitly set the Style attribute of every Button, add another style that's BasedOn this style, but doesn't have a key:

<Style TargetType="{x:Type Button}" BasedOn="{StaticResource ButtonStyle}" />

Using this method, all Buttons in your application will automatically inherit your custom style, but you can still create additional styles BasedOn the ButtonStyle entry and avoid blowing away all of your custom styling.

Solution 3

I think there is no base style defined for "control" so your BasedOn="{StaticResource {x:Type Control}}" part won't find anything.

You probably want to change

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

to

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

Related videos on Youtube

Marcom
Author by

Marcom

Full stack Developer.. Specializing on c#, work on web, mobile, server applications and been playing a bit with F#, Python and machine learning

Updated on July 09, 2022

Comments

  • Marcom
    Marcom almost 2 years

    I have a theme that is applied to all buttons in a resource dictionary. Now I want to add a trigger to the button while inheriting the style changes from the dictionary. I tried the following code, but it says that the control cannot be found. How can I fix it ?

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

    The base template:

        <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>
    
  • Marcom
    Marcom about 13 years
    Can I do it without assigning a name? There is only one style for the control in the dictionary.
  • Pieter Müller
    Pieter Müller about 13 years
    Do you mean that, rather than assign a key to the base style, you would like the extended style to figure out which style to extend based on it's TargetType? I don't know.
  • Pieter Müller
    Pieter Müller about 13 years
    Why do you hesitate to give the base style an x:Key="FooStyle" ?
  • OregonGhost
    OregonGhost almost 6 years
    @PieterMüller: If you assign a key to the style, the style is no longer used by default by all matching controls within the context. Nathan Friend's answer provides a solution for this. I just got the same problem :)

Related