目录
介绍
Toggle Switch按钮
该ThemeSwitch控件是建立在WPF ToggleButton之上的CustomControl。此控件可作为NuGet包下载,并可选择从包含原始源代码和说明的GitHub存储库运行演示项目。
ThemeSwitch通过NuGet包作为多目标框架免费库分发,确保所有WPF版本之间的兼容性。
它具有三种动画类型:
- ValueItem (DoubleAnimation)
- ThickItem (ThicknessAnimation)
- ColorItem (ColorAnimation)
Yutube:使用WPF创建昼夜切换按钮|GitHub源代码|NuGet - YouTube
背景
最初,我受到YouTube视频的启发,该视频展示了在Figma中设计的昼夜切换按钮,我决定在我的专业领域WPF中复制这个概念。最终的结果是非凡的,我很高兴能与其他人分享。这段旅程也让我有机会将我的编码技能和技巧传授给那些对WPF开发有亲和力或目前正在学习WPF开发的人。
1. 项目构成分析
我们通过软件工具进行的分析表明,此按钮是从WPF ToggleButton派生的自定义变体。它由代表白天(太阳/云)和夜晚(月亮/星空)的元素组成。此外,我们还加入了自定义动画,以增强白天到黑夜的过渡效果。
2. 在WPF中绘制特殊形状
有许多方法可以绘制特殊形状,例如使用预先编辑的SVG图像或使用Blend中的路径工具进行绘制。但是,在本项目中,我们演示了如何在没有任何外部设计软件的情况下直接在WPF项目中绘制所需的形状。
- 白天(太阳/云)和夜间(月亮/星空)
- 对于白天模式,可以简单地使用椭圆表示太阳。云虽然看起来很复杂,但创建起来却非常简单。为了实时查看绘图效果,我们在Mainwindow上操作。
我们画一个适当大小的圆圈,并复制它大约八次。可以使用鼠标或箭头键定位这些圆圈,以实现云状外观。Visual Studio根据这些形状的位置生成相应的边距值,然后将其合并到App.xaml中。我们通过添加不同程度的透明度来创造云效果。
<Grid Width="60" Height="30">
<Ellipse Width="17" Height="17" Fill="#FFFFFF" Margin="26,1,16,12"/>
<Ellipse Width="17" Height="17" Fill="#FFFFFF" Margin="38,1,5,12"/>
<Ellipse Width="17" Height="17" Fill="#FFFFFF" Margin="10,12,33,1"/>
<Ellipse Width="17" Height="17" Fill="#FFFFFF" Margin="23,12,20,1"/>
<Ellipse Width="17" Height="17" Fill="#FFFFFF" Margin="32,13,11,0"/>
<Ellipse Width="17" Height="17" Fill="#FFFFFF" Margin="43,8,0,5"/>
<Ellipse Width="17" Height="17" Fill="#FFFFFF" Margin="16,3,27,10"/>
<Ellipse Width="17" Height="17" Fill="#FFFFFF" Margin="5,2,38,11"/>
<Ellipse Width="17" Height="17" Fill="#FFFFFF" Margin="0,8,43,5"/>
</Grid>
- 夜间主题
- 夜晚主题中的星空是使用相同的方法创建的。我们将星空的基本元素定义为矩形,通过调整不透明度来实现亮度效果。我们将基本不透明度设置为55,对于较亮的恒星,我们只需删除不透明度即可。
<Rectangle Width="1" Height="1" Fill="#55FFFFFF" Margin="60,35,19,14"/>
<Rectangle Width="1" Height="1" Fill="#FFFFFF" Margin="36,6,43,43"/>
3. 向项目添加动画
为了生动地呈现按钮的切换效果,我们为每个元素添加了动画。这些动画由jamesnet.WPF Nuget包提供,可简化WPF中的动画集成。
-
元素移动动画——ThickItem
元素的移动是使用jamesnet.WPF中的ThickItem动画实现的(类似于WPF中的ThicknessAnimation)。我们选择“Margin”作为“Property”,使用Cubieaseinout添加更多自然的动画效果,将持续时间设置为0.5秒,并使用边距值来确定移动端点。
<james:ThickItem TargetName="cloud1" Property="Margin" Mode="CubicEaseInOut" Duration="0:0:0.5" To="-70 20 0 0"/>
-
颜色过渡动画——ColorItem
颜色从太阳到月亮或从白天到黑夜元素的过渡是使用 jamesnet. WPF的ColorItem动画实现的(类似于WPF中的ColorAnimation)。常规属性设置类似于ThickItem,但Property语法略有不同:
Ellipse - (Fill).Color;
Border - (Background).Color
“To”部分被更改为所需的颜色。
<james:ColorItem TargetName="ellipse" Property="(Fill).Color"
Mode="CubicEaseInOut" Duration="0:0:0.5" To="#E5B91A"/>
<james:ColorItem TargetName="border" Property="(Background).Color"
Mode="CubicEaseInOut" Duration="0:0:0.5" To="#191C25"/>
-
外观/消失动画——ValueItem
对于夜间模式中的galaxy元素,最初不需要出现,我们使用 jamesnet. WPF的ValueItem动画(相当于WPF中的DoubleAnimation)。我们将Property设置为Opacity和将To设置为0,表示初始不可见状态。
<james:ValueItem TargetName="galaxy" Property="Opacity"
Mode="CubicEaseInOut" Duration="0:0:0.5" To="0"/>
4. 剪辑属性
按照上面概述的代码,我们实现了交替元素移动的效果。但是,我们注意到云层超出了切换按钮的范围,并且仍然可见。为了解决这个问题,我们为项目设置了一个受限区域,将所有元素限制为仅在我们定义的区域内显示。
这是使用Clip属性实现的。
我们使用Geometry,特别是RectangleGeometry,将项目的大小设置为120x50来定义剪切形状。我们还添加了一个角半径值25,确保所有元素仅在指定Clip区域内显示。
<Setter Property="Clip">
<Setter.Value>
<RectangleGeometry Rect="0,0,120,50">
<RectangleGeometry.RadiusX>25</RectangleGeometry.RadiusX>
<RectangleGeometry.RadiusY>25</RectangleGeometry.RadiusY>
</RectangleGeometry>
</Setter.Value>
</Setter>
兴趣点
开发过程带来了独特的挑战,例如,在没有设计人员输入的情况下,仅利用具有简单操作的Visual Studio在WPF编程中满足UI设计要求的可行性。此外,我还探索了通过实现更自然流畅的动画来增强视觉体验。
https://www.codeproject.com/Articles/5372268/Use-WPF-to-Create-a-Day-and-Night-Theme-Switch-But