Title: Make a XAML button library in C#
This example shows how you can build an easily reusable XAML button library in WPF.
The example Make a WPF button template in C# uses a WPF button template to make nice round buttons that change their appearance appropriately when they are disabled, pressed, or when the mouse moves over them.
The button template defines the buttons' basic appearance and behavior, but the program's main XAML code needs to put content on the buttons. For example, the following code hows how the main program defines its Play button.
<Button Template="{StaticResource BubbleButtonTemplate}"
Margin="2" Name="btnPlay" Click="btnPlay_Click">
<Path Stroke="DarkBlue" StrokeLineJoin="Round"
StrokeThickness="2" Fill="White"
Data="M 0,0 L 12,7 0,14 Z"/>
</Button>
That's okay, but what if I want to add multiple copies of the same buttons to the program? Or what if I want to build another program to control a different video? In those cases I would need to copy the code to make the new buttons. (You could also probably compile the buttons into a control library, but I was hoping for an all XAML solution.)
To make a XAML button library, I would like to define a collection of styles that use my button template to define the buttons' appearances. For example, I want a style named BtnPlayStyle that defines a Play button. Then I can make buttons that use that style.
I would have thought this wouldn't be too hard, but there's a pretty big catch. A style uses setters to define control properties but it can't directly set a control's Content property to hold other controls.
Fortunately there's a way around this. The style can define a DataTemplate that indicates how data bound to the control should be displayed. The video buttons don't display bound data, but the DataTemplate can define controls that should go inside the button.
For example, the following code shows the definition of the BtnPlayStyle.
<Style x:Key="BtnPlayStyle" TargetType="Button">
<Setter Property="Template"
Value="{StaticResource BubbleButtonTemplate}"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Path Stroke="DarkBlue" StrokeLineJoin="Round"
StrokeThickness="2" Fill="White"
Data="M 0,0 L 12,7 0,14 Z"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
The DataTemplate contains the Path that defines the Play button's arrow.
The example program's VideoButtons resource dictionary defines all of the video control button styles. The main XAML file includes the library by using a MergedDictionaries object as in the following code.
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="VideoButtons.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Now the main XAML file can use the button library as in the following code.
<Button Style="{StaticResource BtnPlayStyle}" Margin="2"
Name="btnPlay" Click="btnPlay_Click"/>
This is a bit simpler for the Play button, but it makes reusing the button much easier. Not only can you include the same resource dictionary in other projects, but you can also make multiple copies of the same button in a single project.
Download the example to experiment with it and to see additional details.
|