How to trigger an animation with a routed event on a custom control in xaml-WPF C#

78 Views Asked by At

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.

0

There are 0 best solutions below