Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Windows Forms ToggleButton

0.00/5 (No votes)
10 Jul 2014 1  
A Windows Forms toggle button with Android, Windows and iOS like styles.

Introduction

To customize the look and feel of a Windows Forms application, we don't have many options. Especially if we need to use a control for binary options, we always stick to the traditional checkboxes. This control will better help to meet the requirement of using a new control wherever we need a control to represent the binary decision value like "yes" or "no"

Here I'm going to describe the creation of a custom control to represent binary decision with some custom properties and unique UI layer.

What's Supported?

Since customization is the prior focus behind the creation of this control, we can customize almost every element of this ToggleButton. The main properties related to the appearance of the control has been listed below.

  • Toggle Style
  • Toggle State
  • Customized Text
  • Customized Color

These properties and its impact in the control will be described followed by the control creation.

Control Drawing

ToggleButton has been inherited from the Control class of System.Windows.Forms and overrides its OnPaint method to draw the required styles. Since there are different styles supported, the control drawing has been taken care based on the selected style.

protected override void OnPaint(PaintEventArgs e)
        {
            controlBounds = e.ClipRectangle;
            e.Graphics.ResetClip();
            switch (ToggleStyle)
            {
                case ToggleButtonStyle.Android:
                    contentRectangle = e.ClipRectangle;
                    this.BackColor = Color.FromArgb(32, 32, 32);
                    DrawAndroidStyle(e);
                    break;
                case ToggleButtonStyle.Windows:
                    contentRectangle = new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y, this.Width - 1, this.Height - 1);
                    DrawWindowsStyle(e);
                    break;
                case ToggleButtonStyle.IOS:
                    contentRectangle = new Rectangle(0, 0, this.Width, this.Height);
                    DrawIOSStyle(e);
                    break;
                case ToggleButtonStyle.Custom:
                    contentRectangle = new Rectangle(2, 2, this.Width - 3, this.Height - 3);
                    DrawCustomStyle(e);
                    break;
                case ToggleButtonStyle.Metallic:
                    DrawMetallicStyle(e);
                    break;
            }
            base.OnPaint(e);
        }

For each toggle styles, the control's client rectangle will be modified and the region for drawing will be updated. Once the style has been changed, the existing style's regions and graphics path will be reset in order to paint with the new parameters.

For example, let's consider the Android style. The control's region and the points where it should be painted are calculated by the function AndroidPoints() which has been then filled with default / user selected color.

private void DrawAndroidStyle(PaintEventArgs e)
   {
    ...........
    using (SolidBrush sb = new SolidBrush(clr))
            {
                e.Graphics.FillPolygon(sb, AndroidPoints());
            }
    ...........
   }

     private Point[] AndroidPoints()
        {
            p1 = new Point(padx, contentRectangle.Y);
            if (padx == 0)
                p2 = new Point(padx, contentRectangle.Bottom);
            else
                p2 = new Point(padx - SlidingAngle, contentRectangle.Bottom);

            p4 = new Point(p1.X + (contentRectangle.Width / 2), contentRectangle.Y);

            p3 = new Point(p4.X - SlidingAngle, contentRectangle.Bottom);
            if (p4.X == contentRectangle.Right)
                p3 = new Point(p4.X, contentRectangle.Bottom);

            andPoints[0] = p1;
            andPoints[1] = p2;
            andPoints[2] = p3;
            andPoints[3] = p4;
            return andPoints;

            ///p1 -  p4
            ///|     |
            ///p2 -  p3
        }

Similar to the above, for each toggle styles, the control's region and drawing has been modified.

Mouse Interactions

Since this control's main usage relies with the user's mouse interaction on toggling states, it is needed to handle the painting with respect to the mouse gestures to indicate that the state has been changed / toggled.

So in order to achieve this, the OnMouseMove and OnMouseDown events were handled in order to update the drawing of control when a Mouse Button is pressed and moved at the same time.

protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (!this.DesignMode)
            {
                isMouseDown = true;
                downpos = e.Location;
            }
            this.Invalidate();
        }

protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (!this.DesignMode)
            {
                isMouseDown = true;
                downpos = e.Location;
            }
            this.Invalidate();
        }

        protected override void OnMouseMove(MouseEventArgs e)
       {
           if (e.Button == MouseButtons.Left && !this.DesignMode)
            {
                sliderPoint = e.Location;
                isMouseMoved = true;
                if (this.ToggleStyle == ToggleButtonStyle.Android)
                {

                    padx = e.X;
                    if (padx <= contentRectangle.Left + SlidingAngle)
                    {
                        padx = contentRectangle.Left;
                        this.ToggleState = ToggleButtonState.OFF;
                    }

                    if (padx >= contentRectangle.Right - (contentRectangle.Width / 2))
                    {
                        padx = contentRectangle.Right - (contentRectangle.Width / 2);
                        this.ToggleState = ToggleButtonState.ON;
                    }
                }
            }
        }

Using Code

To use this control in an application, either drag and drop from toolbox would work or else just follow the simple steps of code.

     ToggleButton  toggleButton1 = new ToggleButton();
     this.toggleButton1.ToggleStyle = ToggleButton.ToggleButtonStyle.Android;
     this.Controls.Add(this.toggleButton1);

Customization Properties

Toggle Style

Togglebutton supports five styles, namely Android, Windows, iOS, Metallic and Custom. By default, the control uses the Android style appearance, we can change the styles through the ToggleStyle property.

this.toggleButton1.ToggleStyle = ToggleButton.ToggleButtonStyle.Windows;

Toggle State

You can change the toggle state of the button using the property 'ToggleState' which is similar to the CheckedState in the traditional checkbox.

this.toggleButton1.ToggleState = ToggleButton.ToggleButtonState.OFF;

this.toggleButton1.ToggleState = ToggleButton.ToggleButtonState.ON;

Customized Text

We can modify the default text value for the toggle states too, through the 'ActiveText' and 'InActiveText' properties. By default, it uses 'ON' and 'OFF' as default values.

this.toggleButton1.ActiveText = "Yes";

this.toggleButton1.ActiveText = "No";

Customized Color

Similar to the text values, we can also change the color for the active and inactive colors for the control.

this.toggleButton1.ActiveColor = Color.Red

this.toggleButton1.InActiveColor = Color.Blue

Conclusion

With the above approach used in OnPaint() function, we can create and apply new styles to this ToggleButton. :)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here