I am trying to build a WPF custom control to act as a toggle switch using the ToggleButton as base class. I have set up the ResourceDictionary for the style and added to it EventTriggers using the routed events Checked and Unchecked of the ToggleButton to trigger the sliding animation.
When I use the control it shows no signs of interaction, no events are fired, nothing happens. I am fairly new to xaml-WPF control building, so I must be missing something essential.
Here's some code of the relevant code snippets:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Views.Components">
<!-- Colors -->
<Color x:Key="ForestGreenColor">#1AB233</Color>
<Color x:Key="CadetColor">#B0B5C2</Color>
<SolidColorBrush x:Key="ForestGreen" Color="{DynamicResource ForestGreenColor}"/>
<SolidColorBrush x:Key="Cadet" Color="{DynamicResource CadetColor}"/>
<!-- Style -->
<Style TargetType="{x:Type local:Switch}">
<Setter Property="Background" Value="{DynamicResource ForestGreen}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="48"/>
<Setter Property="Height" Value="28"/>
<Setter Property="MaxWidth" Value="48"/>
<Setter Property="MaxHeight" Value="28"/>
<Setter Property="MinWidth" Value="48"/>
<Setter Property="MinHeight" Value="28"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:Switch}">
<Grid>
<Border x:Name="Base"
Background="{TemplateBinding Background}"
CornerRadius="14"
Width="48" Height="28"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<Ellipse x:Name="Switch"
StrokeThickness="0"
Fill="White"
Width="24" Height="24"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="22,0,0,0"/>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Checked">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush)"
To="{StaticResource ForestGreenColor}"
Duration="0:0:0.2"/>
<ThicknessAnimation Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="(Ellipse.Margin)"
To="22,0,0,0"
Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Unchecked">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush)"
To="{StaticResource CadetColor}"
Duration="0:0:0.2"/>
<ThicknessAnimation Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="(Ellipse.Margin)"
To="2,0,0,0"
Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
The corresponding .cs file is bare bones:
public class Switch : ToggleButton
{
static Switch()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Switch), new FrameworkPropertyMetadata(typeof(Switch)));
}
}
And I am using it in its most basic form:
<components:Switch Width="48" Height="28" Margin="0,15,0,0" />
The control displays properly but clicking on it produces nothing. I added a click event to see whether the click is registered, it isn't and I don't know what I am missing. I tried using a Trigger based on the IsChecked property, that worked as it did change the values of the margin and colors, but not through Storyboard, the button jumped and I don't want that. Though it does make me think that I have set up the EventTrigger with the RoutedEvent in a bad way, but I can't figure it out.