Archive for 17th December 2012

Overriding a TargetType Style without a Key in WPF

I have been doing a lot of work in WPF lately, and it is a different animal.

The default styles of a button did not look right for my application, so I came up with the following XAML that styles up all of the button objects in my application:

<Style TargetType="{x:Type Button}">
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="OverridesDefaultStyle" Value="true"/>
    <Setter Property="Background" Value="CornflowerBlue" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border x:Name="Border" CornerRadius="0" BorderThickness="0" 
                            Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding Background}">
                    <ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True" />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter TargetName="Border" Property="Background" Value="#4667A5" />
                    </Trigger>
                    <Trigger Property="IsPressed" Value="true">
                        <Setter TargetName="Border" Property="Background" Value="#3C588C" />
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter TargetName="Border" Property="Background" Value="LightGray" />
                        <Setter TargetName="Border" Property="BorderBrush" Value="#AAAAAA" />
                        <Setter Property="Foreground" Value="DarkGray"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="true">
                        <Setter Property="Foreground" Value="White"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

As you can see, I am using TemplateBinding to bind to the desired background color.

However, in one of my user controls, I want to be able to change the background color of the button in certain situations. Initially, I just created a copy of the above XAML, gave it a Key, and then used that key name to style up the Buttons that I wanted to.

As always, there is a better way. I found that there was a way to use a BasedOn in my new style to pull in the style from the global resources and just change what I needed, here is what it looks like:

<Style x:Key="SpecialButton" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
    <Setter Property="Width" Value="20" />
    <Setter Property="Visibility" Value="Collapsed" />
    <Setter Property="Content" Value=">" />
    <Setter Property="IsTabStop" Value="False" />
    <Setter Property="Background" Value="LightGray" />
</Style>

BTW, Happy Birthday to Eugene Levy, by far one of the funniest actors out there.