WPF ToggleButton 主题切换动画按钮

WPF ToggleButton 主题切换动画按钮

仿造最近看到的html中的一个效果,大致思路是文章这样,感觉还可以再雕琢一下。

代码如下

XAML:

csharp 复制代码
<UserControl x:Class="WPFSwitch.AnimationSwitch"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:icon="http://metro.mahapps.com/winfx/xaml/iconpacks"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WPFSwitch"
             mc:Ignorable="d"
             x:Name="root"
             ClipToBounds="True"
             d:DesignHeight="200" d:DesignWidth="600">
    <UserControl.Resources>
        <local:HalfConverter x:Key="CornerConverter"/>
        <local:HalfConverter x:Key="EllipseConverter" Offset="10"/>
        <Storyboard x:Key="ToDark">
            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border">
                <!--<EasingColorKeyFrame KeyTime="0" Value="DeepSkyBlue"/>-->
                <EasingColorKeyFrame KeyTime="0:0:0.4" Value="#FF081A57"/>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>
        <Storyboard x:Key="ToLight">
            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border">
                <!--<EasingColorKeyFrame KeyTime="0" Value="#FF172E80"/>-->
                <EasingColorKeyFrame KeyTime="0:0:0.4" Value="DeepSkyBlue"/>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>
        <Storyboard x:Key="EllipseColorDark">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Offset)" Storyboard.TargetName="EllipsePoint">
                <EasingDoubleKeyFrame KeyTime="0" Value="0.269"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0.23"/>
            </DoubleAnimationUsingKeyFrames>
            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="EllipsePoint">
                <EasingColorKeyFrame KeyTime="0:0:0.4" Value="#FF318AC9"/>
            </ColorAnimationUsingKeyFrames>
            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="EllipsePoint">
                <EasingColorKeyFrame KeyTime="0:0:0.4" Value="#FF1995EC"/>
            </ColorAnimationUsingKeyFrames>
            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)" Storyboard.TargetName="EllipsePoint">
                <EasingColorKeyFrame KeyTime="0:0:0.4" Value="#FF1A80C9"/>
            </ColorAnimationUsingKeyFrames>
            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)" Storyboard.TargetName="EllipsePoint">
                <EasingColorKeyFrame KeyTime="0:0:0.4" Value="#FF2B72C7"/>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>
        <Storyboard x:Key="EllipseColorLight">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Offset)" Storyboard.TargetName="EllipsePoint">
                <EasingDoubleKeyFrame KeyTime="0" Value="0.269"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0.23"/>
            </DoubleAnimationUsingKeyFrames>
            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="EllipsePoint">
                <EasingColorKeyFrame KeyTime="0:0:0.4" Value="#FFF3EC9A"/>
            </ColorAnimationUsingKeyFrames>
            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="EllipsePoint">
                <EasingColorKeyFrame KeyTime="0:0:0.4" Value="#FFF5EA7E"/>
            </ColorAnimationUsingKeyFrames>
            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)" Storyboard.TargetName="EllipsePoint">
                <EasingColorKeyFrame KeyTime="0:0:0.4" Value="#FFF9E82D"/>
            </ColorAnimationUsingKeyFrames>
            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)" Storyboard.TargetName="EllipsePoint">
                <EasingColorKeyFrame KeyTime="0:0:0.4" Value="#FFF5E42E"/>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>
    </UserControl.Resources>
    <Grid MouseLeftButtonDown="Grid_MouseLeftButtonDown">
        <Viewbox>
            <Grid Width="140" Height="50">
                <Border x:Name="border" Background="DeepSkyBlue" CornerRadius="25" 
                        BorderBrush="#B9616161" BorderThickness="1" ClipToBounds="True">
                    <Grid>
                        <Grid.Clip>
                            <RectangleGeometry Rect="0,0,138,48" RadiusX="24.4" RadiusY="24.4"/>
                        </Grid.Clip>
                        <Grid x:Name="EllipseGrid">
                            <Grid.RenderTransform>
                                <TransformGroup>
                                    <TranslateTransform/>
                                </TransformGroup>
                            </Grid.RenderTransform>
                            <Ellipse Width="150"  Fill="#68FFFFFF"
                                     Height="150" HorizontalAlignment="Left" Margin="-50,-50,0,0" RenderTransformOrigin="0.5,0.5"/>
                            <Ellipse Width="110"  Fill="#68FFFFFF"
                                     Height="110" HorizontalAlignment="Left" Margin="-30,-30,0,0" RenderTransformOrigin="0.5,0.5"/>
                            <Ellipse Width="70"  Fill="#68FFFFFF"
                                     Height="70" HorizontalAlignment="Left" Margin="-10,-10,0,0" RenderTransformOrigin="0.5,0.5"/>
                            
                            <Ellipse x:Name="EllipsePoint" Width="30" 
                                     Height="30" HorizontalAlignment="Left" Margin="10,0,0,0" RenderTransformOrigin="0.5,0.5">
                                <Ellipse.Fill>
                                    <LinearGradientBrush EndPoint="1,1" StartPoint="0,0">
                                        <GradientStop Color="#FFF5EA7E" Offset="0"/>
                                        <GradientStop Color="#FFF3EC9A" Offset="0.269"/>
                                        <GradientStop Color="#FFF5E42E" Offset="0.992"/>
                                        <GradientStop Color="#FFF5E42E" Offset="0.406"/>
                                    </LinearGradientBrush>
                                </Ellipse.Fill>
                                <Ellipse.RenderTransform>
                                    <TransformGroup>
                                        <TranslateTransform x:Name="EllipseTrans"/>
                                    </TransformGroup>
                                </Ellipse.RenderTransform>
                            </Ellipse>
                        </Grid>
                        
                        <Grid x:Name="IconGrid">
                            <Grid x:Name="SunCloudGrid" RenderTransformOrigin="0.5,0.5">
                                <!--<icon:PackIconFontAwesome Kind="CloudSunSolid" Width="60" Height="60" Foreground="#63FFFFFF" Margin="93,-4,0,0"/>
                                <icon:PackIconFontAwesome Kind="CloudSunSolid" Width="60" Height="60" Foreground="White" Margin="91,-2,0,0"/>-->
                                <Path Data="M140.03649,0.5 C174.31957,0.50000232 203.22716,23.515192 212.1514,54.937693 L212.51482,56.280714 214.71126,56.336253 C239.58215,57.59696 259.35999,78.161799 259.35999,103.346 259.35999,105.78318 259.17478,108.1771 258.81763,110.51445 L258.76218,110.825 0.54577836,110.825 0.5,109.01451 C0.50000128,84.43841 17.309905,63.788485 40.059072,57.935381 L42.277143,57.423453 42.711332,56.870943 C50.90431,46.943346 62.38323,39.82807 75.483003,37.190188 L75.597009,37.168902 75.929994,36.589796 C89.076753,14.953116 112.86878,0.50000232 140.03649,0.5 z" 
                                      Fill="White" Stretch="Fill" Width="100" Height="40" Margin="70,10,0,0" Stroke="LightBlue"/>
                                <Path Data="M170.52264,0.5 C219.33329,0.50000092 258.90214,36.481308 258.90214,80.866501 L258.90031,81.006393 260.1909,81.235977 C284.46287,86.183579 302.72114,107.57654 302.72114,133.2175 302.72114,138.71199 301.88276,144.01141 300.32645,148.99577 L300.09232,149.685 0.5,149.685 0.65243936,147.48024 C2.8387119,123.8002 21.045399,104.93561 43.97329,102.53514 L45.555958,102.41107 45.977451,101.19357 C51.924091,84.76516 65.185784,71.106079 82.4888,63.029331 L84.567932,62.114323 84.92556,60.781658 C94.734032,26.115599 129.33865,0.50000098 170.52264,0.5 z" 
                                      Fill="White" Stretch="Fill" Width="60" Height="25" Margin="30,25,0,0" Stroke="LightBlue"/>
                                <Path Data="M129.5925,0.5 C155.34856,0.5 178.3615,12.244667 193.56796,30.670631 L194.60806,31.994179 196.60826,32.455826 C220.50822,38.605011 239.32399,57.420778 245.47318,81.320744 L245.71149,82.353296 247.39884,82.924233 C263.86366,88.95281 275.614,104.76169 275.614,123.315 275.614,147.06325 256.36224,166.315 232.614,166.315 224.49693,166.315 216.90515,164.06592 210.42787,160.15692 L209.35029,159.47861 209.09481,159.60947 C200.17642,163.90678 190.17644,166.315 179.614,166.315 171.39876,166.315 163.52379,164.85818 156.23332,162.18878 L155.89217,162.05427 155.70113,162.1204 C147.49229,164.84182 138.71444,166.315 129.5925,166.315 118.86081,166.315 108.60535,164.276 99.192406,160.56426 L98.768471,160.39105 97.980812,160.79446 C89.062424,165.09178 79.062447,167.5 68.5,167.5 30.944641,167.5 0.5,137.05537 0.5,99.500004 0.5,63.705048 28.157349,34.369812 63.268051,31.698284 L64.890251,31.595482 65.617043,30.670631 C80.823494,12.244667 103.83644,0.5 129.5925,0.5 z" 
                                      Fill="White" Stretch="Fill" Width="60" Height="25" Margin="70,33,0,0" Stroke="LightBlue"/>

                            </Grid>

                            <Grid x:Name="MoonCloudGrid" Margin="0 250 0 0" RenderTransformOrigin="0.5,0.5" >
                                <Path Data="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z" 
                                       Width="10" Height="10" Stretch="Fill" Fill="White" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="50,-5,0,0"/>
                                <Path Data="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z" 
                                       Width="10" Height="10" Stretch="Fill" Fill="White" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="70,5,0,0"/>
                                <Path Data="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z" 
                                       Width="10" Height="10" Stretch="Fill" Fill="White" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="55,18,0,0"/>

                                <Path Data="M43.516087,0.5 L43.081577,2.1057148 C41.396305,8.6558394 40.5,15.522644 40.5,22.598793 40.5,67.886138 77.212654,104.59879 122.5,104.59879 L124.2612,104.57651 123.89148,105.08343 C111.39967,121.78695 91.462456,132.59879 69,132.59879 31.168495,132.59879 0.5,101.9303 0.5,64.098793 0.5,35.725166 17.751028,11.380729 42.336708,0.98186255 z" 
                                      Width="40" Height="40" Stretch="Fill" Fill="White" HorizontalAlignment="Left" Margin="10,-12,0,0"/>

                            </Grid>
                        </Grid>
                       
                    </Grid>
                </Border>
            </Grid>
        </Viewbox>
    </Grid>
</UserControl>

C#

csharp 复制代码
public partial class AnimationSwitch : UserControl
{
    public AnimationSwitch()
    {
        InitializeComponent();
    }


    public bool IsChecked
    {
        get { return (bool)GetValue(IsCheckedProperty); }
        set { SetValue(IsCheckedProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsChecked.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsCheckedProperty =
        DependencyProperty.Register("IsChecked", typeof(bool), typeof(AnimationSwitch), new PropertyMetadata(false));


    private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (!IsChecked)
        {
            Storyboard sb = new Storyboard();
            DoubleAnimation daStart = new DoubleAnimation(-10, new Duration(TimeSpan.FromMilliseconds(200)));
            sb.Children.Add(daStart);

            DoubleAnimation daToRight = new DoubleAnimation(90, new Duration(TimeSpan.FromMilliseconds(250)))
            {
                BeginTime = TimeSpan.FromMilliseconds(200),
                EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut }
            };
            sb.Children.Add(daToRight);
            Storyboard.SetTarget(daStart, EllipseGrid);
            Storyboard.SetTargetProperty(daStart, new PropertyPath("RenderTransform.Children[0].X"));
            Storyboard.SetTarget(daToRight, EllipseGrid);
            Storyboard.SetTargetProperty(daToRight, new PropertyPath("RenderTransform.Children[0].X"));
            sb.Begin();

            ThicknessAnimation daIcon = new ThicknessAnimation(new Thickness(0, -240, 0, 0), new Duration(TimeSpan.FromMilliseconds(400)));
            daIcon.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut };
            IconGrid.BeginAnimation(MarginProperty, daIcon);

            Storyboard toDark = FindResource("ToDark") as Storyboard;
            toDark.Begin();
            Storyboard EllipseColorDark = FindResource("EllipseColorDark") as Storyboard;
            EllipseColorDark.Begin();
        }
        else
        {
            Storyboard sb = new Storyboard();
            DoubleAnimation daStart = new DoubleAnimation(98, new Duration(TimeSpan.FromMilliseconds(200)));
            sb.Children.Add(daStart);

            DoubleAnimation daToRight = new DoubleAnimation(0, new Duration(TimeSpan.FromMilliseconds(250)))
            {
                BeginTime = TimeSpan.FromMilliseconds(200),
                EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut }
            };
            sb.Children.Add(daToRight);
            Storyboard.SetTarget(daStart, EllipseGrid);
            Storyboard.SetTargetProperty(daStart, new PropertyPath("RenderTransform.Children[0].X"));
            Storyboard.SetTarget(daToRight, EllipseGrid);
            Storyboard.SetTargetProperty(daToRight, new PropertyPath("RenderTransform.Children[0].X"));
            sb.Begin();

            ThicknessAnimation daIcon = new ThicknessAnimation(new Thickness(0), new Duration(TimeSpan.FromMilliseconds(400)));
            daIcon.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut };
            IconGrid.BeginAnimation(MarginProperty, daIcon);

            Storyboard toLight = FindResource("ToLight") as Storyboard;
            toLight.Begin();
            Storyboard EllipseColorLight = FindResource("EllipseColorLight") as Storyboard;
            EllipseColorLight.Begin();
        }

        IsChecked = !IsChecked;
    }
}
相关推荐
samble1 小时前
从零搭建灌装监控系统(十九):单元测试实战,xUnit + 内存SQLite + 反射测试私有方法
c#·wpf·mvvm·modbus·工业控制
人道领域4 小时前
【面试八股速通篇01】锁与并发工具
java·开发语言·面试·c#
宇卿.4 小时前
C#字段、属性、索引器、常量
开发语言·计算机视觉·c#
程序员Linc4 小时前
ONNXOCRSharp 开源手记 02|v0.4.0 PDF识别
开发语言·pdf·c#·ocr·onnxocrsharp
慧都小妮子5 小时前
MSG 附件太占内存?Aspose.Email for .NET 26.9 延迟加载
c#·.net·aspose·内存优化·延迟加载·aspose.email·附件内存
慧都小妮子5 小时前
FastReport PDF/UA 导出:让出海 PDF 满足无障碍合规要求
pdf·c#·fastreport·报表导出·pdf/ua·pdf 无障碍
淡海水9 小时前
03-02-架构篇-Boehm GC架构解析
unity·架构·c#·gc·boehm
光泽雨19 小时前
路由概念和路由事件 继承链路 RadioButton的事件解析
wpf
samble1 天前
从零搭建灌装监控系统(十八):自定义控件,三色灯与状态指示
c#·wpf·mvvm·modbus·工业控制
jun_bai1 天前
使用Aspose实现word文档合并,内容替换
windows·c#·word