How to base a style on another style in a resource dictionary?
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 Button
s 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}}" >
Related videos on Youtube
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, 2022Comments
-
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 about 13 yearsCan I do it without assigning a name? There is only one style for the control in the dictionary.
-
Pieter Müller about 13 yearsDo 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 about 13 yearsWhy do you hesitate to give the base style an x:Key="FooStyle" ?
-
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 :)