Archive for the ‘WPF’ Category.

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">
            <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" />
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter TargetName="Border" Property="Background" Value="#4667A5" />
                    <Trigger Property="IsPressed" Value="true">
                        <Setter TargetName="Border" Property="Background" Value="#3C588C" />
                    <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 Property="IsEnabled" Value="true">
                        <Setter Property="Foreground" Value="White"/>

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" />

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

Using the new WPF themes

So I am looking around for some ideas on making this WPF based application for Windows that I am working on look slightly less sucky. And I see some nifty themes on this web page:

WPF Themes

And I am thinking that would be pretty cool to just swap in one line in the App.xaml file, and my whole app would look different.

Cool in theory, but some implementation details are a bit fuzzy.

Here is what I did to get it working with VS 2010 Ultimate:

  • Install the WPF Toolkit by clicking on the big purple “download” button on the above web site
  • Download the themes xaml files by going to this web site: WP Futures (scroll down to WP Themes and click the link to download the zip file)
  • Unzip the downloaded file and add the needed xaml files to your WPF project
  • Add a reference to WPF Toolkit in your application’s References folder
  • Add a ResourceDictionary line to the Application.Resources section of your App.xaml file to make it look like the one shown on the WPF Themes page above

Keep in mind that if you put your xaml theme files in a folder off the root of your project, you will need to adjust the Source property of the ResourceDictionary. For example, I put the xaml theme files in a Themes folder off the root of the project, so the Source for me looks like this:

<ResourceDictionary Source="/Themes/ExpressionDark.xaml" />

BTW, Happy Birthday to John Petrucci, who is quite clearly not a native of this planet.