Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Toggle Switch Control in Windows Forms

I am designing a toggle switch control using CheckBox, but currently my control only draws a circle. How can I draw round shapes like the below image and how can I change the location of the circle based on the value of the control to represent checked and unchecked states like the below image?

Enter image description here

Here is my code:

public class MyCheckBox:CheckBox
{
    public MyCheckBox()
    {
        this.Appearance = System.Windows.Forms.Appearance.Button;
        this.BackColor = Color.Transparent;
        this.TextAlign = ContentAlignment.MiddleCenter;
        this.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
        this.FlatAppearance.BorderColor = Color.RoyalBlue;
        this.FlatAppearance.BorderSize = 2;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        this.OnPaintBackground(e);
        using (var path = new GraphicsPath())
        {
            var c = e.Graphics.ClipBounds;
            var r = this.ClientRectangle;
            r.Inflate(-FlatAppearance.BorderSize, -FlatAppearance.BorderSize);
            path.AddEllipse(r);
            e.Graphics.SetClip(path);
            base.OnPaint(e);
            e.Graphics.SetClip(c);
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            if (this.Checked)
            {
                using (var p = new Pen(FlatAppearance.BorderColor,
                                       FlatAppearance.BorderSize))
                {
                    e.Graphics.DrawEllipse(p, r);
                }
            }
        }
    }
}
like image 500
GOPAL YADAV Avatar asked Jul 18 '16 08:07

GOPAL YADAV


1 Answers

I know this is a Windows Forms question. But you may want to take a look at Toggle Switches or read more about Universal Windows App Components.

Anyway, here is an answer for Windows Forms developers. It shows how we can customize rendering of a checkbox to have such appearance.

Currently you are drawing only an ellipse, and it's quite a toggle button. But if you want to show it like the below image, you should first draw a round shape for background, and then based on the Checked value, draw the check circle. Using the code in Example part of the answer you can have a CheckBox with such a UI:

Enter image description here

Example

The important thing about this sample is it's completely a CheckBox control and supports check using mouse and keyboard. It also supports data-binding and all other standard features of CheckBox. The code is not perfect, but it is a good start point to have a yes/no toggle switch:

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

public class MyCheckBox : CheckBox
{
    public MyCheckBox()
    {
        SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
        Padding = new Padding(6);
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        this.OnPaintBackground(e);
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
        using (var path = new GraphicsPath())
        {
            var d = Padding.All;
            var r = this.Height - 2 * d;
            path.AddArc(d, d, r, r, 90, 180);
            path.AddArc(this.Width - r - d, d, r, r, -90, 180);
            path.CloseFigure();
            e.Graphics.FillPath(Checked ? Brushes.DarkGray : Brushes.LightGray, path);
            r = Height - 1;
            var rect = Checked ? new Rectangle(Width - r - 1, 0, r, r)
                               : new Rectangle(0, 0, r, r);
            e.Graphics.FillEllipse(Checked ? Brushes.Green : Brushes.WhiteSmoke, rect);
        }
    }
}
like image 71
Reza Aghaei Avatar answered Oct 26 '22 22:10

Reza Aghaei