Ok, it’s a really dumb title for a blog post, but this is just a little love for WPF and its ability to completely restyle a standard control.

In our most recent project, we have a list of groups of pigs that we show the user so they can choose one to work with. The groups might be male, female, castrates or mixed, and we need to let the user filter the list by sex so that there’s not as many to choose from.

We ended up using RadioButtons, one for each sex. As an example, here’s the XAML for the “Females” option:

    <RadioButton Grid.Column="2" 
                 Tag="{x:Static qfp:ProgenySex.Female}"
                 ToolTip="Show only female groups">
        <Label>_Females</Label>
    </RadioButton>

However, we knew that the filtering options in the finished product shouldn’t look like radio buttons. In fact, the effect I wanted was closer to the FlatButtons appearance on the TabControl in Windows Forms:

image

In the end, with a little bit of XAML templating, I was able to achieve exactly the look I wanted. It’s even better than the TabControl! Here’s a screenshot:

image

So the “buttons” at the top of the list are actually RadioButtons (using the XAML above), and in this screenshot the user has selected “Females”. Below is a part of the XAML we used to restyle the radio buttons (I’ve omitted the icon setters etc). It just goes to show how powerful WPF is!

<Style TargetType="{x:Type RadioButton}"> <EventSetter Event="ToggleButton.Checked" Handler="SetProgenySexFilter" /> <Setter Property="Focusable" Value="False" /> <Setter Property="GroupName" Value="filter"/> <Setter Property="IsTabStop" Value="False" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RadioButton}"> <ControlTemplate.Resources> <Style TargetType="{x:Type Image}"> <Setter Property="Height" Value="16" /> <Setter Property="Width" Value="16" /> <Setter Property="VerticalAlignment" Value="Center"/> <Setter Property="Margin" Value="0,0,2,0" /> </Style> <Style TargetType="{x:Type TextBlock}"> <Setter Property="VerticalAlignment" Value="Center"/> </Style> <Style TargetType="{x:Type Label}"> <Setter Property="Padding" Value="0"/> </Style> </ControlTemplate.Resources> <Border x:Name="PART_border" CornerRadius="2" Padding="3px" Margin="2px" Background="Transparent" BorderThickness="1" BorderBrush="{x:Static SystemColors.ControlDarkBrush}" SnapsToDevicePixels="True"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <Image x:Name="PART_icon" /> <ContentPresenter x:Name="PART_content" /> </StackPanel> </Border> <ControlTemplate.Triggers> <Trigger Property="IsChecked" Value="True"> <Setter TargetName="PART_content" Property="TextBlock.FontWeight" Value="Bold"/> <Setter TargetName="PART_border" Property="Background"> <Setter.Value> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="{x:Static SystemColors.ControlLightColor}"

Offset="0"/> <GradientStop Color="{x:Static SystemColors.ControlColor}"

Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> </Trigger>