339 lines
13 KiB
C#
339 lines
13 KiB
C#
using System;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Windows.Forms;
|
|
|
|
namespace JinYuan.ControlLib
|
|
{
|
|
public enum ControlType
|
|
{
|
|
/// <summary>
|
|
/// 椭圆
|
|
/// </summary>
|
|
Ellipse,
|
|
/// <summary>
|
|
/// 矩形
|
|
/// </summary>
|
|
Rectangle,
|
|
/// <summary>
|
|
/// 直线
|
|
/// </summary>
|
|
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;
|
|
|
|
}
|
|
}
|