Search code examples
wpfstylesdefaultcontroltemplatetemplatebinding

WPF ControlTemplate: How to provide a default value for TemplateBinding?


I am writing a WPF control that subclasses a Button. I then provide a default style in Themes\generic.xaml, that looks like this (simplified):

<Style TargetType="{x:Type WPFControls:MyButton}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type WPFControls:MyButton}">
                <Button 
                    x:Name="PART_Button"
                    Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

I would like the user to have the opportunity to change the control's background, but if he doesn't, I'd like to provide default value. How do I do it?

When I do it like in the posted code, the Background and BorderBrush is null (= nonexistent) unless user explicitly specifies them (which effectively forces user to always provide some value), but the standard windows controls (like Button) provide a default look, that can still be customized by user. How to do this in my control?

Thank you!

Solution by Michael Morton:

You can provide defaults as setters in style:

<Style TargetType="{x:Type TestTemplate:MyButton}">
    <Setter Property="Background" Value="Red" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TestTemplate:MyButton}">
                <Button 
                    x:Name="PART_Button"
                    IsEnabled="{TemplateBinding IsEnabled}"
                    Content="{TemplateBinding Content}"
                    Background="{TemplateBinding Background}"
                    />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Usage:

<StackPanel>
    <TestTemplate:MyButton Background="Blue">Explicitly blue</TestTemplate:MyButton>
    <TestTemplate:MyButton>Naturally red</TestTemplate:MyButton>
</StackPanel>

Solution

  • You can just define setters on your style for the two properties in question.

    For example, some general definitions:

    <LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#F3F3F3" Offset="0"/>
        <GradientStop Color="#EBEBEB" Offset="0.5"/>
        <GradientStop Color="#DDDDDD" Offset="0.5"/>
        <GradientStop Color="#CDCDCD" Offset="1"/>
    </LinearGradientBrush>
    
    <SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
    

    Then, in your style definition:

    <Setter Property="Background" Value="{StaticResource ButtonNormalBackground}" />
    <Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}" />