Skip to content

vickyqu115/themeswitch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

94 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

How to create a day and night theme switch button using WPF

The ThemeSwitch control is a customizable WPF ToggleButton-based control with three types of animations and is available as a NuGet Package, accompanied by a GitHub repository for the source code and instructions, designed to add engaging visual elements to WPF applications.


Introduction

Toggle Switch Button The ThemeSwitch control is a CustomControl built on top of the WPF ToggleButton. This control is accessible for download as a NuGet Package, with the option to run a demo project from a GitHub repository that includes the original source code and instructions.

The ThemeSwitch is distributed as a multi-targeting framework free library through NuGet Package, ensuring compatibility across all WPF versions.

It features three animation types:

  • ValueItem (DoubleAnimation)
  • ThickItem (ThicknessAnimation)
  • ColorItem (ColorAnimation)

Youtube: English+Korean Sub
BiliBili: Chinese
CodeProject:Use WPF to Create a Day and Night Theme Switch Button
NuGet:NuGet Gallery | ThemeSwitch 1.0.0.8

Background

Initially inspired by a YouTube video showcasing a day-to-night switch button designed in Figma, I took it upon myself to replicate the concept in WPF, my area of expertise. The final outcome was remarkable, and I am excited to share it with others. This journey also offered me the opportunity to impart my coding skills and tips to those who have an affinity for or are currently learning WPF development.

1.Project Composition Analysis:

image

Our analysis through software tools reveals that this button is a custom variant derived from the WPF ToggleButton. It comprises elements representing day (sun/clouds) and night (moon/starry sky). Additionally, we have incorporated custom animations to enhance the day-to-night transition effect.

2.Drawing Special Shapes in WPF:

There are numerous methods for drawing special shapes, such as using pre-edited SVG images or drawing with the Path tool in Blend. However, in this project, we demonstrate how to directly draw our desired shapes within the WPF project without any external design software.

  • Daytime (Sun/Clouds) and Nighttime (Moon/Starry Sky):

    For the daytime mode, the sun can be simply represented using the ellipse. The clouds, although seemingly complex, are quite straightforward to create. To see the drawing effects in real-time, we operate in the Mainwindow. We draw an appropriately sized circle and replicate it about eight times. These circles can be positioned using the mouse or arrow keys to achieve a cloud-like appearance. Visual Studio generates corresponding margin values based on the positions of these shapes, which we then incorporate into App.xaml. We create a cloud effect by adding varying degrees of transparency.

    image

    image

    image

    <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>
  • Night Theme:

    The starry sky in the night theme is created using the same method. We define the basic elements of the starry sky as rectangles, with the brightness effect achieved by adjusting the opacity. We set the basic opacity to 55, and for brighter stars, we simply remove the opacity.

    <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.Adding Animations to the Project:

To vividly present the button's toggling effect, we add animations to each element. These animations are facilitated by the jamesnet.WPF Nuget Package, which simplifies animation integration in WPF.

Element Movement Animation - ThickItem: The movement of elements is achieved using the ThickItem animation from jamesnet.WPF (akin to ThicknessAnimation in WPF). We select "Margin" for the "Property", add more natural animation effects using Cubieaseinout, set the duration to 0.5 seconds, and use margin values to determine movement endpoints.

<james:ThickItem TargetName="cloud1" Property="Margin" Mode="CubicEaseInOut" Duration="0:0:0.5" To="-70 20 0 0"/>
  • Color Transition Animation - ColorItem:

    The transition of colors from the sun to the moon or from day to night elements is achieved using the ColorItem animation from jamesnet.WPF (similar to ColorAnimation in WPF). The general property settings are akin to ThickItem, but with a slight variation in Property syntax: Ellipse - (Fill).Color; Border - (Background).Color. The 'To' part is altered to the desired color.

     <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"/>
  • Appearance/Disappearance Animation - ValueItem:

    For the galaxy element in the night mode, which doesn't need to appear initially, we use the ValueItem animation from jamesnet.WPF (equivalent to DoubleAnimation in WPF). We set the Property to Opacity and To to 0, indicating an initially invisible state.

    <james:ValueItem TargetName="galaxy" Property="Opacity" Mode="CubicEaseInOut" Duration="0:0:0.5" To="0"/>

4.Clip Property:

Following the code outlined above, we achieve the effect of alternating element movement. However, we noticed that the clouds extend beyond the toggle button's range and remain visible. To address this, we set a confined area for the project, restricting all elements to display only within our defined region. This is achieved using the Clip property. We define a clipping shape using Geometry, specifically RectangleGeometry, with the project's size set to 120x50. We also add a corner radius value of 25, ensuring that all elements are displayed only within the designated Clip area.

<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>

Points of Interest

The development process brought forth unique challenges, such as the feasibility of fulfilling UI design requirements in WPF programming without a designer's input, solely utilizing Visual Studio with straightforward operations. Furthermore, I explored enhancing visual experiences by implementing more naturally flowing animations.


Video 1 Video 2
IMG_7822.MOV
IMG_7825.MOV

Contributors

Thanks go to these wonderful people (List made with contrib.rocks):

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Packages

No packages published

Languages