Animated Switch ToggleButton Style in WPF

This post will show you how to implement an animated switch in WPF. This was done with inspiration from uilang.com‘s animated switch and from iOS.

switch

The animation’s keysplines were determined using this tool: http://www.carto.net/papers/svg/samples/keysplines.svg

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <Page.Resources>
      <ResourceDictionary>
         <Style x:Key="AnimatedSwitch" TargetType="{x:Type ToggleButton}">
            <Setter Property="Foreground" Value="Black" />
            <Setter Property="Background" Value="#FAFAFB" />
            <Setter Property="BorderBrush" Value="#EAEAEB" />
            <Setter Property="Template">
               <Setter.Value>
                  <ControlTemplate TargetType="ToggleButton">
                     <Viewbox Stretch="Uniform">
                        <Canvas Name="Layer_1" Width="20" Height="20" Canvas.Left="10" Canvas.Top="0">
                           <Ellipse  Canvas.Left="0" Width="20" Height="20" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="0.5"/>
                           <Ellipse  Canvas.Left="15" Width="20" Height="20" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="0.5"/>
                           <Border Canvas.Left="10" Width="15" Height="20" Name="rect416927" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,0.5,0,0.5"/>
                           <Ellipse x:Name="ellipse"  Canvas.Left="0" Width="20" Height="20" Fill="White" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="0.3">
                              <Ellipse.RenderTransform>
                                 <TranslateTransform X="0" Y="0" />
                              </Ellipse.RenderTransform>
                              <Ellipse.BitmapEffect>
                                 <DropShadowBitmapEffect Softness="0.1" ShadowDepth="0.7" Direction="270" Color="#BBBBBB"/>
                              </Ellipse.BitmapEffect>
                           </Ellipse>
                        </Canvas>
                     </Viewbox>
                     <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked" Value="True" >
                           <Trigger.EnterActions>
                              <BeginStoryboard>
                                 <Storyboard>
                                    <ColorAnimation Storyboard.TargetProperty="Background.Color" To="#52D468" Duration="0:0:0.2" />
                                    <ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="#41C955" Duration="0:0:0.2" />
                                    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(TranslateTransform.X)" Storyboard.TargetName="ellipse">
                                       <SplineDoubleKeyFrame KeyTime="0" Value="0"/>
                                       <SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="15" KeySpline="0, 1, 0.6, 1"/>
                                    </DoubleAnimationUsingKeyFrames>
                                 </Storyboard>
                              </BeginStoryboard>
                           </Trigger.EnterActions>
                           <Trigger.ExitActions>
                              <BeginStoryboard>
                                 <Storyboard>
                                    <ColorAnimation Storyboard.TargetProperty="Background.Color" To="#FAFAFB" Duration="0:0:0.2" />
                                    <ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="#EAEAEB" Duration="0:0:0.2" />
                                    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(TranslateTransform.X)" Storyboard.TargetName="ellipse">
                                       <SplineDoubleKeyFrame KeyTime="0" Value="15"/>
                                       <SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="0" KeySpline="0, 0.5, 0.5, 1"/>
                                    </DoubleAnimationUsingKeyFrames>
                                 </Storyboard>
                              </BeginStoryboard>
                           </Trigger.ExitActions>
                        </Trigger>
                     </ControlTemplate.Triggers>
                  </ControlTemplate>
               </Setter.Value>
            </Setter>
         </Style>
      </ResourceDictionary>
   </Page.Resources>
   <Grid>
      <ToggleButton Style="{StaticResource AnimatedSwitch}" Height="80"/>
   </Grid>
</Page>
  • movgp0

    Why net set up a GitHub Repository with XAML Components for Material design? I am sure the community might help.

  • Emilien Guimineau

    The movgp0’s idea is good (imho), because you done a great job (with this article and the other one about the ToggleButton)

  • Syed Moshiur Murshed

    Awesome stuff!!
    Just in case anyone needs a different disabled style
    Put it inside the

    other triggers ……

    • Muhammed Thabjeel

      how to change the position of the switch. It won’t changes by giving margin. Help?

  • alam disoja

    Its great stuff. I am very new to WPF. I can add it in the WPF application but want to create custom library for the same. How can I do that?

  • Adam Chapman

    This clicks on, but doesn’t click off… Any ideas? Works on one project but not another..