WPF button style and template

Junior222 picture Junior222 · Aug 19, 2014 · Viewed 13.1k times · Source

So i have the button and its style:

<Style TargetType="Button" x:Key="BaseButtonStyle">
    <Setter Property="FontWeight" Value="Bold"  />
    <Setter Property="Width" Value="120" />
    <Setter Property="Height" Value="30" />
    <Setter Property="BorderBrush" Value="#1FA3FF"  />
</Style>

<Style TargetType="{x:Type Button}" x:Key="MyButtonStyle"  BasedOn="{StaticResource BaseButtonStyle}">          
    <Setter Property="Background" Value="#1FA3EB"  />
    <Setter Property="Foreground" Value="#FFFFFF"  />
</Style>

<Button Style="{StaticResource MyButtonStyle}" Content="My text" />

It works fine and i have the following results (aquamarine background isn't part of Button, it belongs to Window):

enter image description here

But then i want to replace button's content and change my style so:

<Style TargetType="{x:Type Button}" x:Key="MyButtonStyle"  BasedOn="{StaticResource BaseButtonStyle}">          
    <Setter Property="Background" Value="#1FA3EB"  />
    <Setter Property="Foreground" Value="#FFFFFF"  />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="√" />
                    <TextBlock Text="{TemplateBinding Button.Content}" />
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

and now my button becomes awful:

enter image description here

As you can see my button lost its borders and background and it doesn't change its view when mouse is over it. Where am i wrong and what should i do to prevent it?

UPD

when i do something like this:

<Style TargetType="{x:Type Button}" x:Key="MyButtonStyle"  BasedOn="{StaticResource BaseButtonStyle}">          
    <Setter Property="Background" Value="#1FA3EB"  />
    <Setter Property="Foreground" Value="#FFFFFF"  />
    <Setter Property="Content" >
        <Setter.Value>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="√" />
                <TextBlock Text="{TemplateBinding Button.Content}" />
            </StackPanel>
        </Setter.Value>
    </Setter>
</Style>

then i get this result:

enter image description here

As you can see this is similar to the firstresult, where the check mark is missing

Answer

Sheridan picture Sheridan · Aug 19, 2014

The look and functionality of the default Button is defined in the default ControlTemplate for the Button (you can find that in the Button Styles and Templates page on MSDN). As you changed the ControlTemplate, the default look and behaviour is now gone and replaced with your plain StackPanel and TextBlock elements.

When providing a new ControlTemplate for controls, it is a good idea to start with the default ControlTemplate and make small changes until you have your desired look. Here is a slight extension to your Style that provides some basic mouse over functionality:

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate>
            <Border BorderBrush="Black" BorderThickness="1" CornerRadius="3">
                <Border.Style>
                    <Style TargetType="{x:Type Border}">
                        <Setter Property="Background" Value="LightBlue" />
                        <Style.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" Value="LightGreen" />
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="√" />
                <TextBlock Text="{TemplateBinding Button.Content}" />
                </StackPanel>
            </Border>
        </ControlTemplate>
    </Setter.Value>
</Setter>

You can find out more about ControlTemplates from the ControlTemplate Class page on MSDN.