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.