Here's my quick contribution. This is a far more complete version of TheCardinal's code. This is all in code so you can add it to your project and it will show up in the designer's toolbox (no namespace - it'll be at the top). The default event is set so you can double-click the control and it will fill out a CheckChanged event handler for you. Colors, borders, and the ON/OFF label are customizable. It exposes a property called Checked just like a checkbox control.
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
public class CheckChangedEventArgs : EventArgs
{
public bool OldValue { get; set; }
public bool NewValue { get; set; }
public CheckChangedEventArgs(bool old_value, bool new_value)
{
NewValue = new_value;
OldValue = old_value;
}
}
public delegate void CheckChangedEventHandler(object sender, CheckChangedEventArgs e);
[DefaultEvent("CheckChanged")]
public class ToggleSwitch : UserControl
{
private Color _ColorToggleOn = Color.Green;
private Color _ColorToggleOff = Color.Red;
private Color _ColorButtonOn = Color.Honeydew;
private Color _ColorButtonOff = Color.Snow;
private string _TextON = "ON";
private string _TextOFF = "OFF";
private bool _checked = false;
private bool _BorderExtraThin = true;
private bool _BorderForButton = true;
private int _ButtonWidthPercentage = 30;
public Color ColorToggleOn { get { return _ColorToggleOn; } set { _ColorToggleOn = value; UpdateColors(); } }
public Color ColorToggleOff { get { return _ColorToggleOff; } set { _ColorToggleOff = value; UpdateColors(); } }
public Color ColorButtonOn { get { return _ColorButtonOn; } set { _ColorButtonOn = value; UpdateColors(); } }
public Color ColorButtonOff { get { return _ColorButtonOff; } set { _ColorButtonOff = value; UpdateColors(); } }
public string TextON { get { return _TextON; } set { _TextON = value; UpdateColors(); } }
public string TextOFF { get { return _TextOFF; } set { _TextOFF = value; UpdateColors(); } }
public bool BorderExtraThin { get { return _BorderExtraThin; } set { _BorderExtraThin = value; UpdateBorders(); UpdateColors(); Refresh(); } }
public bool BorderForButton { get { return _BorderForButton; } set { _BorderForButton = value; UpdateBorders(); UpdateColors(); Refresh(); } }
public int ButtonWidthPercentage { get { return _ButtonWidthPercentage; } set { _ButtonWidthPercentage = value; UpdateBorders(); UpdateColors(); Refresh(); } }
public bool Checked
{
get { return _checked; }
set
{
if (Checked == value)
return;
_checked = value;
UpdateColors();
CheckChanged(this, new CheckChangedEventArgs(!Checked, Checked));
}
}
private Label label1;
[Category("Action")]
[Description("Fires when the switch is toggled, just like a checkbox")]
public event CheckChangedEventHandler CheckChanged;
void _CheckChangedDoNothing(object sender, CheckChangedEventArgs e)
{
}
public ToggleSwitch()
{
CheckChanged = new CheckChangedEventHandler(_CheckChangedDoNothing);
label1 = new Label();
label1.ForeColor = this.ForeColor;
label1.Visible = true;
label1.TextAlign = ContentAlignment.MiddleCenter;
label1.BorderStyle = BorderStyle.FixedSingle;
label1.MouseDown += new MouseEventHandler(label1_MouseDown);
this.Controls.Add(label1);
UpdateColors();
}
void label1_MouseDown(object sender, EventArgs e)
{
Clicked();
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
Clicked();
}
private void Clicked()
{
Checked = !Checked;
}
private void UpdateBorders()
{
if (BorderExtraThin)
{
BorderStyle = System.Windows.Forms.BorderStyle.None;
}
if (BorderForButton)
{
label1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
}
}
private void UpdateColors()
{
if (Checked)
{
this.BackColor = ColorToggleOn;
this.label1.Dock = DockStyle.Right;
label1.Width = (ClientRectangle.Width * ButtonWidthPercentage) / 100;
this.label1.Text = TextON;
this.label1.BackColor = ColorButtonOn;
this.label1.Padding = new Padding(1, 0, 0, 0);
this.Refresh();
}
else
{
this.BackColor = ColorToggleOff;
this.label1.Dock = DockStyle.Left;
label1.Width = (ClientRectangle.Width * ButtonWidthPercentage) / 100;
this.label1.Text = TextOFF;
this.label1.BackColor = ColorButtonOff;
this.Refresh();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
int BORDER_SIZE = 1;
if (BorderExtraThin)
{
ControlPaint.DrawBorder(e.Graphics, ClientRectangle,
Color.Black, BORDER_SIZE, ButtonBorderStyle.Inset,
Color.Black, BORDER_SIZE, ButtonBorderStyle.Inset,
Color.Black, BORDER_SIZE, ButtonBorderStyle.Inset,
Color.Black, BORDER_SIZE, ButtonBorderStyle.Inset);
}
}
}