One of my favorite things about WPF is that you can make controls look like anything you want. You want a button with text? <Button><TextBlock /></Button> You want a button with an image? <Button><Image /></Button>
So, when I was adding closeable tab functionality to my application, I figured it would be a breeze. When I added the button to the tab header, though, something undesirable happened: it looked like a button. I wanted a close button that just looked like an “X,” not the usual 3D Windows button. Luckily, this is easily accomplished through the use of control templates.
Creating a custom button is a two-step process:
- Create a ControlTemplate
- Apply the template
Here’s a short example of what I did to create a simple “X” close button:
<Window.Resources>
<ControlTemplate x:Key="buttonTemplate" TargetType="Button">
<Path Data="M0,0 L8,8 M8,0 L0,8" Margin="5,5,0,0" Stroke="Black" StrokeThickness="3" />
</ControlTemplate>
</Window.Resources>
<Button Template="{StaticResource ResourceKey=buttonTemplate}" />
This works just fine, but I’ve created a usability problem. When the user sees or interacts with the button, there are no visual indicators that the item is clickable or anything happens when it’s clicked. No problems, though; we can fix these problems with a pair of style triggers.
<Window.Resources>
<ControlTemplate x:Key="buttonTemplate" TargetType="Button">
<Path Data="M0,0 L8,8 M8,0 L0,8" Margin="5,5,0,0" StrokeThickness="3">
<Path.Style>
<Style TargetType="{x:Type Path}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Stroke" Value="LightGray" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Stroke" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
</ControlTemplate>
</Window.Resources>
<Button Template="{StaticResource ResourceKey=buttonTemplate}" />
Now when you hover over the button, the X turns red. This is the perfect button for my closeable tab.
