using System; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace JinYuan.ControlLib { public enum ControlType { /// /// 椭圆 /// Ellipse, /// /// 矩形 /// Rectangle, /// /// 直线 /// Line } [DefaultEvent("CheckedChanged")] public partial class Toggle : UserControl { public Toggle() { InitializeComponent(); //设置控件样式 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.DoubleBuffer, true); this.SetStyle(ControlStyles.ResizeRedraw, true); this.SetStyle(ControlStyles.Selectable, true); this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); this.MouseDown += Toggle_MouseDown; } private void Toggle_MouseDown(object sender, MouseEventArgs e) { IsChecked = !IsChecked; CheckedChanged?.Invoke(this, e); } private ControlType controlType = ControlType.Ellipse; [Browsable(true)] [Category("自定义属性")] [Description("设置或获取控件的样式")] public ControlType ControlType { get { return controlType; } set { controlType = value; this.Invalidate(); } } private Color trueColor = Color.FromArgb(73, 119, 232); [Browsable(true)] [Category("自定义属性")] [Description("设置或获取控件选中的颜色")] public Color TrueColor { get { return trueColor; } set { trueColor = value; this.Invalidate(); } } private Color falseColor = Color.FromArgb(180, 180, 180); [Browsable(true)] [Category("自定义属性")] [Description("设置或获取控件未选中的颜色")] public Color FalseColor { get { return falseColor; } set { falseColor = value; this.Invalidate(); } } private bool isChecked = false; [Browsable(true)] [Category("自定义属性")] [Description("设置或获取控件是否选中")] public bool IsChecked { get { return isChecked; } set { isChecked = value; this.Invalidate(); } } private string trueText = string.Empty; [Browsable(true)] [Category("自定义属性")] [Description("设置或获取控件选中的文本")] public string TrueText { get { return trueText; } set { trueText = value; this.Invalidate(); } } private string falseText = string.Empty; [Browsable(true)] [Category("自定义属性")] [Description("设置或获取控件未选中的文本")] public string FalseText { get { return falseText; } set { falseText = value; this.Invalidate(); } } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics graphics = e.Graphics; graphics.SmoothingMode = SmoothingMode.AntiAlias; graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; //获取填充颜色 Color fillColor = isChecked ? trueColor : falseColor; //创建路径 GraphicsPath path = new GraphicsPath(); //文本 string text = isChecked ? trueText : falseText; //文件尺寸 SizeF size = graphics.MeasureString(text, this.Font); //间隙 int gap = 2; //小圆宽度 int border = 2; switch (controlType) { case ControlType.Ellipse: float r = (this.Height - 2) * 0.5f; //添加直线 path.AddLine(new Point(this.Height / 2, 1), new Point(this.Width - this.Height / 2, 1)); //添加圆弧 path.AddArc(new RectangleF(this.Width - 2 * r - 1, 1, 2 * r, 2 * r), -90, 180); //添加直线 path.AddLine(new PointF(this.Width - r - 1, this.Height - 1), new Point(this.Height / 2, this.Height - 1)); //添加圆弧 path.AddArc(new RectangleF(1, 1, 2 * r, 2 * r), 90, 180); graphics.FillPath(new SolidBrush(fillColor), path); //大圆半径 float radius = (this.Height - 2 * (1 + gap)) * 0.5f; //如果选中如何绘制 if (isChecked) { graphics.FillEllipse(Brushes.White, new RectangleF(this.Width - 2 * radius - gap - 1, gap + 1, 2 * radius, 2 * radius)); //如果文本为空,则画小圆,否则,写文字 if (string.IsNullOrEmpty(text)) { graphics.DrawEllipse(new Pen(Color.White, border), new RectangleF(this.Height * 0.5f - radius * 0.5f, this.Height * 0.5f - radius * 0.5f, radius, radius)); } else { graphics.DrawString(text, this.Font, Brushes.White, new PointF(this.Height * 0.5f - size.Height * 0.5f, this.Height * 0.5f - size.Height * 0.5f)); } } else { graphics.FillEllipse(Brushes.White, new RectangleF(gap + 1, gap + 1, 2 * radius, 2 * radius)); //如果文本为空,则画小圆,否则,写文字 if (string.IsNullOrEmpty(text)) { graphics.DrawEllipse(new Pen(Color.White, border), new RectangleF(this.Width - (1.5f * radius + 1), this.Height * 0.5f - radius * 0.5f, radius, radius)); } else { graphics.DrawString(text, this.Font, Brushes.White, new PointF(this.Width - (this.Height * 0.5f - size.Height * 0.5f) - size.Width, this.Height * 0.5f - size.Height * 0.5f)); } } break; case ControlType.Rectangle: int intRadius = 3; //添加圆弧1 path.AddArc(new RectangleF(1, 1, intRadius * 2, intRadius * 2), 180, 90); //添加圆弧2 path.AddArc(new RectangleF(this.Width - 2 * intRadius - 1, 1, intRadius * 2, intRadius * 2), 270, 90); //添加圆弧3 path.AddArc(new RectangleF(this.Width - 2 * intRadius - 1, this.Height - 2 * intRadius - 1, intRadius * 2, intRadius * 2), 0, 90); //添加圆弧4 path.AddArc(new RectangleF(1, this.Height - 2 * intRadius - 1, intRadius * 2, intRadius * 2), 90, 90); graphics.FillPath(new SolidBrush(fillColor), path); if (isChecked) { path = new GraphicsPath(); int inwidth = this.Height - 2 * (gap + 1); //添加圆弧1 path.AddArc(new RectangleF(this.Width - inwidth - gap - 1, 1 + gap, intRadius * 2, intRadius * 2), 180, 90); //添加圆弧2 path.AddArc(new RectangleF(this.Width - 1 - gap - 2 * intRadius, 1 + gap, intRadius * 2, intRadius * 2), 270, 90); //添加圆弧3 path.AddArc(new RectangleF(this.Width - 1 - gap - 2 * intRadius, this.Height - 2 * intRadius - 1 - gap, intRadius * 2, intRadius * 2), 0, 90); //添加圆弧4 path.AddArc(new RectangleF(this.Width - inwidth - gap - 1, this.Height - 2 * intRadius - 1 - gap, intRadius * 2, intRadius * 2), 90, 90); graphics.FillPath(Brushes.White, path); radius = inwidth * 0.5f; //如果文本为空,则画小圆,否则,写文字 if (string.IsNullOrEmpty(text)) { graphics.DrawEllipse(new Pen(Color.White, border), new RectangleF(this.Height * 0.5f - radius * 0.5f, this.Height * 0.5f - radius * 0.5f, radius, radius)); } else { graphics.DrawString(text, this.Font, Brushes.White, new PointF(this.Height * 0.5f - size.Height * 0.5f, this.Height * 0.5f - size.Height * 0.5f)); } } else { path = new GraphicsPath(); int inwidth = this.Height - 2 * (gap + 1); //添加圆弧1 path.AddArc(new RectangleF(1 + gap, 1 + gap, intRadius * 2, intRadius * 2), 180, 90); //添加圆弧2 path.AddArc(new RectangleF(inwidth + 1 + gap - 2 * intRadius, 1 + gap, intRadius * 2, intRadius * 2), 270, 90); //添加圆弧3 path.AddArc(new RectangleF(inwidth + 1 + gap - 2 * intRadius, this.Height - 2 * intRadius - 1 - gap, intRadius * 2, intRadius * 2), 0, 90); //添加圆弧4 path.AddArc(new RectangleF(1 + gap, this.Height - 2 * intRadius - 1 - gap, intRadius * 2, intRadius * 2), 90, 90); graphics.FillPath(Brushes.White, path); radius = inwidth * 0.5f; //如果文本为空,则画小圆,否则,写文字 if (string.IsNullOrEmpty(text)) { graphics.DrawEllipse(new Pen(Color.White, border), new RectangleF(this.Width - (1.5f * radius + 1), this.Height * 0.5f - radius * 0.5f, radius, radius)); } else { graphics.DrawString(text, this.Font, Brushes.White, new PointF(this.Width - (this.Height * 0.5f - size.Height * 0.5f) - size.Width, this.Height * 0.5f - size.Height * 0.5f)); } } break; case ControlType.Line: float bigRadius = (this.Height - 2) * 0.5f; float smallRadius = bigRadius * 0.5f; path = new GraphicsPath(); //添加直线1 path.AddLine(new PointF(1 + bigRadius + smallRadius, 1 + smallRadius), new PointF(this.Width - (1 + bigRadius + smallRadius), 1 + smallRadius)); //添加圆弧1 path.AddArc(new RectangleF(this.Width - (1 + bigRadius + smallRadius * 2), 1 + smallRadius, smallRadius * 2, smallRadius * 2), -90, 180); //添加直线2 path.AddLine(new PointF(this.Width - (1 + bigRadius + smallRadius), 1 + smallRadius + bigRadius), new PointF(1 + bigRadius + smallRadius, 1 + smallRadius + bigRadius)); //添加圆弧2 path.AddArc(new RectangleF(1 + bigRadius, 1 + smallRadius, smallRadius * 2, smallRadius * 2), 90, 180); graphics.FillPath(new SolidBrush(fillColor), path); if (isChecked) { graphics.FillEllipse(new SolidBrush(fillColor), new RectangleF(this.Width - (1 + bigRadius * 2), 1, bigRadius * 2, bigRadius * 2)); graphics.FillEllipse(Brushes.White, new RectangleF(this.Width - (1 + bigRadius + smallRadius), 1 + smallRadius, smallRadius * 2, smallRadius * 2)); } else { graphics.FillEllipse(new SolidBrush(fillColor), new RectangleF(1, 1, bigRadius * 2, bigRadius * 2)); graphics.FillEllipse(Brushes.White, new RectangleF(1 + smallRadius, 1 + smallRadius, smallRadius * 2, smallRadius * 2)); } break; default: break; } } [Browsable(true)] [Category("自定义事件")] [Description("选中发生变化触发")] public event EventHandler CheckedChanged; } }