I've done this in the past by defining an attached property called ExtendedProperties.CornerRadius
. I can then set it in my style:
<Style TargetType="Button">
<Setter Property="local:ExtendedProperties.CornerRadius" Value="0"/>
...
And use it from within the template:
<Border CornerRadius="{Binding Path=(local:ExtendedProperties.CornerRadius), RelativeSource={RelativeSource TemplatedParent}">
I might then override it locally in the same way I override any other property:
<Button Content="Archive" local:ExtendedProperties.CornerRadius="5,0,0,5"/>
<Button Content="Span"/>
<Button Content="Delete" local:ExtendedProperties.CornerRadius="0,5,5,0"/>
In my case, this gives me (obviously, my theme is dark):
And just by tweaking a couple of my theme's attached properties, I created this effect:
The advantage of this approach is that there's no need to subclass Button
. You can also use that same attached property to define corner radii for other controls (such as TextBox
). And you're not limited to just corner radius, of course. You could define attached properties for all sorts of things specific to your theme that aren't present on base controls.
The disadvantage is that it's an attached property and thus harder to discover. Documenting your theme will help in this respect.
So, to answer your specific questions:
Q1. Yes, see my answer above. You can either override locally or define new styles that override the property.
Q2. It's a gray area. In my opinion, if it's purely visual (not behavioural) then styles are the way to go. Of course, if it gets out of hand you may instead wish to subclass all the built-in controls and add your specific properties. But that makes your theme harder to re-use and your application more onerous to develop (because you need to use your control set rather than the standard ones).
Q3. I'd say it's possible in code, but not intuitive to use as a control consumer. I think you'd be better off defining extra attached properties - eg. ExtendedProperties.HoverBackground
, ExtendedProperties.PressedBackground
- and using those from your template in exactly the same way. Then consumers of your control then have more control over the brushes used when your control is in its various states. I've done this in the past but have used more generic property names (SecondaryBackground
, TernaryBackground
) so I can reuse those properties in other contexts. Again, documenting your theme is helpful.