首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

WPF 怎么把checkbox改成开关样式

编程知识
2024年08月16日 15:59

先看一下效果吧:

isChecked = false 的时候的效果

isChecked = true 的时候的效果

 然后我们来实现一下这个效果吧

第一步:创建一个空的wpf项目;

第二步:在项目里面添加一个checkbox

    <Grid>
        <CheckBox HorizontalAlignment="Center" IsChecked="True"
                  BorderBrush="Black" VerticalAlignment="Center" 
                  Content="switch" Background="#FF00ADFF"/>
    </Grid>

这个时候的checkbox的样子是这样的

 第三步:在页面中右键checkbox,选择  编辑模板 ,再  编辑副本, 之后确定

 vs就会给我们自动生成一个名为 CheckBoxStyle1” Checkbox的默认样式的代码,我们通过修改默认样式的代码,把普通的Checkbox变成一个开关。

 第四步:修改默认样式

                        <Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <Border x:Name="PART_Border" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" 
                                    BorderThickness="1" Height="14" Width="25" CornerRadius="5">
                                <Border x:Name="SwitchBorder" BorderThickness="1" BorderBrush="Gray" Background="White" Width="10" 
                                        Margin="1" CornerRadius="5" HorizontalAlignment="Right"/>
                            </Border>
                            <ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                              Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Grid>

把之前的样式代码改成上面的代码,trigger部分,把报错的部分全部删除

这个时候,我们的开关样式就已经完成了

 我们现在需要添加一些trigger和动画来实现切换效果

第五步:添加动画和trigger

<Storyboard x:Key="SwitchChecked">
    <DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchBorder" Storyboard.TargetProperty="(FrameworkElement.Width)">
        <EasingDoubleKeyFrame KeyTime="00:00:00" Value="10"/>
        <EasingDoubleKeyFrame KeyTime="00:00:00.2500000" Value="20"/>
        <EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="10"/>
    </DoubleAnimationUsingKeyFrames>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchBorder" Storyboard.TargetProperty="(FrameworkElement.HorizontalAlignment)">
        <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static HorizontalAlignment.Left}"/>
        <DiscreteObjectKeyFrame KeyTime="00:00:00.2500000" Value="{x:Static HorizontalAlignment.Right}"/>
        <DiscreteObjectKeyFrame KeyTime="00:00:00.5000000" Value="{x:Static HorizontalAlignment.Right}"/>
    </ObjectAnimationUsingKeyFrames>
</Storyboard>

<Storyboard x:Key="SwitchUnchecked">
    <DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchBorder" Storyboard.TargetProperty="(FrameworkElement.Width)">
        <EasingDoubleKeyFrame KeyTime="00:00:00" Value="10"/>
        <EasingDoubleKeyFrame KeyTime="00:00:00.2500000" Value="20"/>
        <EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="10"/>
    </DoubleAnimationUsingKeyFrames>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchBorder" Storyboard.TargetProperty="(FrameworkElement.HorizontalAlignment)">
        <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static HorizontalAlignment.Right}"/>
        <DiscreteObjectKeyFrame KeyTime="00:00:00.2500000" Value="{x:Static HorizontalAlignment.Left}"/>
        <DiscreteObjectKeyFrame KeyTime="00:00:00.5000000" Value="{x:Static HorizontalAlignment.Left}"/>
    </ObjectAnimationUsingKeyFrames>
</Storyboard>

上面这段代码就是表示不同状态下的不同动画效果,通过改变SwitchBoder的宽度和对齐方式,就可以实现了

然后我们再把这段动画效果运用到模板中,再添加3个trigger,就可以了

                        <ControlTemplate.Triggers>
                            <Trigger Property="HasContent" Value="true">
                                <Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual}"/>
                                <Setter Property="Padding" Value="4,-1,0,0"/>
                            </Trigger>
                            <EventTrigger RoutedEvent="{x:Static CheckBox.CheckedEvent}">
                                <BeginStoryboard Storyboard="{StaticResource SwitchChecked}"/>
                            </EventTrigger>
                            <EventTrigger RoutedEvent="{x:Static CheckBox.UncheckedEvent}">
                                <BeginStoryboard Storyboard="{StaticResource SwitchUnchecked}"/>
                            </EventTrigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Background" TargetName="PART_Border" Value="{StaticResource OptionMark.Disabled.Background}"/>
                                <Setter Property="BorderBrush" TargetName="PART_Border" Value="{StaticResource OptionMark.Disabled.Border}"/>
                            </Trigger>
                            <Trigger Property="IsChecked" Value="False">
                                <Setter Property="Background" Value="White" TargetName="PART_Border"/>
                                <Setter Property="HorizontalAlignment" Value="Left" TargetName="SwitchBorder"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="BorderBrush" TargetName="PART_Border" Value="{StaticResource OptionMark.MouseOver.Border}"/>
                            </Trigger>

                        </ControlTemplate.Triggers>

到现在,样式和动画就已经完成了,我们再把代码全部剪切到App.xaml这个项目资源文件下面,再删掉style的命名,x:Key="CheckBoxStyle1"删掉,

这样子我们的项目里面的checkbox就都是开关的样式了,运行项目也不会报错啦,最后的代码如下

 

    <Application.Resources>

        <Storyboard x:Key="SwitchChecked">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchBorder" Storyboard.TargetProperty="(FrameworkElement.Width)">
                <EasingDoubleKeyFrame KeyTime="00:00:00" Value="10"/>
                <EasingDoubleKeyFrame KeyTime="00:00:00.2500000" Value="20"/>
                <EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="10"/>
            </DoubleAnimationUsingKeyFrames>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchBorder" Storyboard.TargetProperty="(FrameworkElement.HorizontalAlignment)">
                <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static HorizontalAlignment.Left}"/>
                <DiscreteObjectKeyFrame KeyTime="00:00:00.2500000" Value="{x:Static HorizontalAlignment.Right}"/>
                <DiscreteObjectKeyFrame KeyTime="00:00:00.5000000" Value="{x:Static HorizontalAlignment.Right}"/>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>

        <Storyboard x:Key="SwitchUnchecked">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchBorder" Storyboard.TargetProperty="(FrameworkElement.Width)">
                <EasingDoubleKeyFrame KeyTime="00:00:00" Value="10"/>
                <EasingDoubleKeyFrame KeyTime="00:00:00.2500000" Value="20"/>
                <EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="10"/>
            </DoubleAnimationUsingKeyFrames>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchBorder" Storyboard.TargetProperty="(FrameworkElement.HorizontalAlignment)">
                <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static HorizontalAlignment.Right}"/>
                <DiscreteObjectKeyFrame KeyTime="00:00:00.2500000" Value="{x:Static HorizontalAlignment.Left}"/>
                <DiscreteObjectKeyFrame KeyTime="00:00:00.5000000" Value="{x:Static HorizontalAlignment.Left}"/>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>


        <Style x:Key="FocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Margin="2" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key="OptionMarkFocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Margin="14,0,0,0" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <SolidColorBrush x:Key="OptionMark.Static.Background" Color="#FFFFFFFF"/>
        <SolidColorBrush x:Key="OptionMark.Static.Border" Color="#FF707070"/>
        <SolidColorBrush x:Key="OptionMark.Static.Glyph" Color="#FF212121"/>
        <SolidColorBrush x:Key="OptionMark.MouseOver.Background" Color="#FFF3F9FF"/>
        <SolidColorBrush x:Key="OptionMark.MouseOver.Border" Color="#FF5593FF"/>
        <SolidColorBrush x:Key="OptionMark.MouseOver.Glyph" Color="#FF212121"/>
        <SolidColorBrush x:Key="OptionMark.Pressed.Background" Color="#FFD9ECFF"/>
        <SolidColorBrush x:Key="OptionMark.Pressed.Border" Color="#FF3C77DD"/>
        <SolidColorBrush x:Key="OptionMark.Pressed.Glyph" Color="#FF212121"/>
        <SolidColorBrush x:Key="OptionMark.Disabled.Background" Color="#FFE6E6E6"/>
        <SolidColorBrush x:Key="OptionMark.Disabled.Border" Color="#FFBCBCBC"/>
        <SolidColorBrush x:Key="OptionMark.Disabled.Glyph" Color="#FF707070"/>
        <Style TargetType="{x:Type CheckBox}">
            <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
            <Setter Property="Background" Value="{StaticResource OptionMark.Static.Background}"/>
            <Setter Property="BorderBrush" Value="{StaticResource OptionMark.Static.Border}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type CheckBox}">
                        <Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <Border x:Name="PART_Border" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" 
                                    BorderThickness="1" Height="14" Width="25" CornerRadius="5">
                                <Border x:Name="SwitchBorder" BorderThickness="1" BorderBrush="Gray" Background="White" Width="10" 
                                        Margin="1" CornerRadius="5" HorizontalAlignment="Right"/>
                            </Border>
                            <ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                              Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="HasContent" Value="true">
                                <Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual}"/>
                                <Setter Property="Padding" Value="4,-1,0,0"/>
                            </Trigger>
                            <EventTrigger RoutedEvent="{x:Static CheckBox.CheckedEvent}">
                                <BeginStoryboard Storyboard="{StaticResource SwitchChecked}"/>
                            </EventTrigger>
                            <EventTrigger RoutedEvent="{x:Static CheckBox.UncheckedEvent}">
                                <BeginStoryboard Storyboard="{StaticResource SwitchUnchecked}"/>
                            </EventTrigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Background" TargetName="PART_Border" Value="{StaticResource OptionMark.Disabled.Background}"/>
                                <Setter Property="BorderBrush" TargetName="PART_Border" Value="{StaticResource OptionMark.Disabled.Border}"/>
                            </Trigger>
                            <Trigger Property="IsChecked" Value="False">
                                <Setter Property="Background" Value="White" TargetName="PART_Border"/>
                                <Setter Property="HorizontalAlignment" Value="Left" TargetName="SwitchBorder"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="BorderBrush" TargetName="PART_Border" Value="{StaticResource OptionMark.MouseOver.Border}"/>
                            </Trigger>

                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        
    </Application.Resources>

 

 

 

 

 下面是广告:

项目github地址:bearhanQ/WPFFramework: Share some experience (github.com)

QQ技术交流群:332035933;

From:https://www.cnblogs.com/lvpp13/p/18363225
本文地址: http://shuzixingkong.net/article/1164
0评论
提交 加载更多评论
其他文章 games101 作业4及作业5 详解光线追踪框架
games101 作业4及作业5 详解光线追踪框架 作业4 代码分析 作业四的代码整体比较简单 主要流程就是 通过鼠标事件 获取四个控制点的坐标 然后绘制贝塞尔曲线的内容就由我们来完成 理论分析 贝塞尔曲线的理论就是给定一组控制点 然后不断的在控制点之间进行插值 再在得到的新的插值点之间进行插值 具
games101 作业4及作业5 详解光线追踪框架 games101 作业4及作业5 详解光线追踪框架 games101 作业4及作业5 详解光线追踪框架
.NET8 Blazor 从入门到精通:(二)组件
目录Blazor 组件基础路由导航参数组件参数路由参数生命周期事件状态更改组件事件 Blazor 组件 基础 新建一个项目命名为 MyComponents ,项目模板的交互类型选 Auto ,其它保持默认选项: 客户端组件 (Auto/WebAssembly): 最终解决方案里面会有两个项目:服务器
.NET8 Blazor 从入门到精通:(二)组件 .NET8 Blazor 从入门到精通:(二)组件 .NET8 Blazor 从入门到精通:(二)组件
别再被坑了! JavaScript类型检测的最佳实践
别再被坑了! JavaScript类型检测的最佳实践 在 JavaScript 中,我们经常需要判断一个变量的类型。这个需求在编程中非常常见,因为不同类型的数据会影响到我们的代码逻辑。 JavaScript 提供了几种方法来检测数据类型,每种方法都有自己的优缺点。 Object.prototype.
别再被坑了! JavaScript类型检测的最佳实践
mysql8.0 主从架构模式【0到1架构系列】
前提条件 准备3,4,5台虚拟机 祼装mysql8.0 主从架构 常见两种模式“一主多从”和“级联复制”两种,基本都很简单,都是依赖binlog日志文件进行同步,binlog日志会记录DDL和部分DDL语句,进行同步时从库会重新执行这些语句从而实现主从同步。 步骤1: 配置主/从服务器的server
mysql8.0 主从架构模式【0到1架构系列】 mysql8.0 主从架构模式【0到1架构系列】 mysql8.0 主从架构模式【0到1架构系列】
CRC算法原理、推导及实现
CRC, Cyclic Redundancy Check, 循环冗余校验 1. 基本原理 CRC的本质是除法,把待检验的数据当作一个很大(很长)的被除数,两边选定一个除数(有的文献叫poly),最后得到的余数就是CRC的校验值。 判定方法: 将消息和校验和分开。计算消息的校验和(在附加W个零后),并
树莓派CM4(三): 定制自己的树莓派镜像
1. 镜像下载 使用树莓派最新的镜像Raspberry Pi OS Lite,内核版本6.6 下载链接 https://downloads.raspberrypi.com/raspios_lite_arm64/images/raspios_lite_arm64-2024-07-04/2024-07-
树莓派CM4(三): 定制自己的树莓派镜像 树莓派CM4(三): 定制自己的树莓派镜像 树莓派CM4(三): 定制自己的树莓派镜像
unity游戏源码和教程:智能分析话语的三维唯美世界
unity游戏源码和教程:智能分析话语的三维唯美世界。 这个游戏的源码(含教程文档)我放到了夸克网盘https://pan.quark.cn/s/618fb9459029 话语分析是有用的,假如游戏中,你是队长,带着NPC队友张三和李四,路上遇到蛇,你可以说“张三打蛇,李四保护张三。”这就需要先分析
unity游戏源码和教程:智能分析话语的三维唯美世界 unity游戏源码和教程:智能分析话语的三维唯美世界 unity游戏源码和教程:智能分析话语的三维唯美世界
Unity FPSSample Demo研究
1.前言 Unity FpsSample Demo大约是2018发布,用于官方演示MLAPI(NetCode前身)+DOTS的一个FPS多人对战Demo。 Demo下载地址(需要安装Git LFS) :https://github.com/Unity-Technologies/FPSSample 下
Unity FPSSample Demo研究 Unity FPSSample Demo研究 Unity FPSSample Demo研究