Search code examples
wpfxamluser-controls

Customising a button without adding a border or other content


I have a WPF button

<Button Style="{StaticResource BrandedButton}">Continue</Button>

It's currently styled as follows:

<Style x:Key="BrandedButton" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="{StaticResource LowlightBrush}"/>
    <Setter Property="Foreground" Value="White"/>
    <Setter Property="FontFamily" Value="Open Sans Light"/>
    <Setter Property="FontSize" Value="35"/>
    <Setter Property="Padding" Value="50,10"/>
</Style>

enter image description here

Now, I want to control the colour (and nothing else) for hover/press/etc, so I've added another setter

    <Setter Property="Template" Value="{StaticResource BrandedButtonTemplate}"/>

And that points at this ControlTemplate. I've only seen examples which change the structure of the button, eg by adding a border:

<ControlTemplate x:Key="BrandedButtonTemplate" TargetType="Button">
    <Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="0">
        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="true">
            <Setter Property="Background" Value="{StaticResource HighlightBrush}"/>
        </Trigger>
        <Trigger Property="IsPressed" Value="true">
            <Setter Property="Background" Value="{StaticResource HighlightBrush}"/>
        </Trigger>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Background" Value="{StaticResource HighlightBrush}"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

But that kills the layout that was previously applied:

enter image description here

Conversely, if I only include the ContentPresenter and omit the wrapping Border, the button disappears entirely.

How can I change the hover and press colours without changing anything else? What's the smallest/lightest implementation for what should be a trivial task?


Solution

  • Your ControlTemplate ignores the Button's Padding property.

    Add a TemplateBinding of the ContentPresenter's Margin:

    <ControlTemplate x:Key="BrandedButtonTemplate" TargetType="Button">
        <Border Background="{TemplateBinding Background}" BorderThickness="0">
            <ContentPresenter
                Margin="{TemplateBinding Padding}"
                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        </Border>
        <ControlTemplate.Triggers>
            ...
        </ControlTemplate.Triggers>
    </ControlTemplate>