I have been working on several Wpf projects. In every project we needed to style the default Wpf controls (e.g. Button). Everytime we started on a new project we built our templates and styles from scratch - or simply copied them from one assembly to another.
Because I hate copying and recreating the same code over and over again I want to collect those styles and move them into one place so I can use them across multiple projects with much less effort.
An example of modification (again using the Button control): We need to change brushes of different button states to fit the requirements for the application.
| Hover-Brush | Click-Effect |
|-----------|-------------|----------------|
| Project A | Orange | Light Orange |
| Project B | Blue | Light Blue |
| ... | ... | ... |
In order to achieve my goal I need to abstract this samplestyle:
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" Background="Orange">
<!-- Further elements required to build our button -->
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="LightOrange" />
</Trigger>
<!-- Further triggers for other effects -->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
As you can see the colors are hardcoded and due to that the style is not reusable. My idea is to use attached properties the style can use for binding. If I would define an attached property HoverBrush
and use it for binding the new style would look like this:
<Style TargetType="{x:Type Button}"
x:Key="DefaultButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" Background="{TemplateBinding Background}">
<!-- Further elements required to build our button -->
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border"
Property="Background"
Value="{Binding Path=styles:Brushes.HoverBrush,
RelativeSource={RelativeSource TemplatedParent},
FallbackValue={StaticResource SomeBrush}}" />
</Trigger>
<!-- Further triggers for other effects -->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This style would reduce the markup required for a new theme in a different application to something like this:
<Style TargetType="{x:Type Button}"
BasedOn="{StaticResource DefaultButton}">
<Setter Property="styles:Brushes.HoverBrush"
Value="LightOrange" />
</Style>
So my question(s) would be: Are there different approaches? Do you see some negative sides to my approach? And most important: Do you know more effective ways to achieve my goal?
Since each new app will be themed I would just define some brushes in Generic.xaml and do {DynamicResource HoverBrush}.
The xaml for the button style could stay the same, and in each new app you would just need to define new brushes with those same names in Generic.xaml