C# GDI+绘制开关按钮(SwitchButton)
实现效果
编写路线
这里我们将重写Panel的绘画函数,一个开关按钮包含两种状态,开或关。
所以我们先定义一个属性来表示开关的状态:
private bool status = false;
[Browsable(true), DefaultValue(typeof(bool)), Description("按钮状态")]
[Category("Appearance")]
public bool Status
{
get
{
return status;
}
set
{
status = value;
base.Invalidate();
}
}
同时打开和关闭两种状态的颜色我们也需要定义:
[Browsable(true), DefaultValue(typeof(Color)), Description("打开的圆角饼背景颜色")]
[Category("Appearance")]
public Color RoundCakeColor_Open { get; set; } = Color.White;
[Browsable(true), DefaultValue(typeof(Color)), Description("关闭的圆角饼背景颜色")]
[Category("Appearance")]
public Color RoundCakeColor_Close { get; set; } = Color.White;
[Browsable(true), DefaultValue(typeof(Color)), Description("打开的圆角矩形背景颜色")]
[Category("Appearance")]
public Color RoundBackColor_Open { get; set; } = Color.Green;
[Browsable(true), DefaultValue(typeof(Color)), Description("关闭的圆角矩形背景颜色")]
[Category("Appearance")]
public Color RoundBackColor_Close { get; set; } = Color.Gray;
接下来是打开和关闭后显示的文字
[Browsable(true), DefaultValue(typeof(string)), Description("打开的文字")]
[Category("Appearance")]
public string RoundText_Open { get; set; } = "已开启";
[Browsable(true), DefaultValue(typeof(string)), Description("关闭的文字")]
[Category("Appearance")]
public string RoundText_Close { get; set; } = "已关闭";
[Browsable(true), DefaultValue(typeof(Color)), Description("打开的文字的颜色")]
[Category("Appearance")]
public Color RoundTextColor_Open { get; set; } = Color.White;
[Browsable(true), DefaultValue(typeof(Color)), Description("关闭的文字的颜色")]
[Category("Appearance")]
public Color RoundTextColor_Close { get; set; } = Color.Black;
随后重新鼠标的按下和放开虚函数,在里面修改我们要改变的内容
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
Status = !Status;
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.MouseUp"/> event.
/// </summary>
/// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data.</param>
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (e.Button != MouseButtons.Left) return;
base.Invalidate();
}
最重要的一个环节就是画按钮了,这里我分为画矩形,画圆,画字等
//画字
public static void DrawRoundText(string text, Font font ,Graphics g, Brush brush, PointF pointF)
{
g.DrawString(text, font, brush, pointF);
}
//画圆饼
public static void DrawRoundCake(Graphics g, Brush brush , Rectangle rect)
{
Rectangle RoundCakeRect = rect;
RoundCakeRect.X = RoundCakeRect.X;
RoundCakeRect.Y = RoundCakeRect.Y + 5;
RoundCakeRect.Width = RoundCakeRect.Width - 10;
RoundCakeRect.Height = RoundCakeRect.Height - 10;
g.FillEllipse(brush, RoundCakeRect);
}
//画圆角矩形
public static void DrawRoundRectangle(Graphics g, Brush brush, Rectangle rect, int cornerRadius)
{
using (GraphicsPath path = CreateRoundedRectanglePath(rect, cornerRadius))
{
g.FillPath(brush, path);
}
}
//填充矩形
public static void FillRoundRectangle(Graphics g, Brush brush, Rectangle rect, int cornerRadius)
{
using (GraphicsPath path = CreateRoundedRectanglePath(rect, cornerRadius))
{
g.FillPath(brush, path);
}
}
//获取圆角矩形路径
internal static GraphicsPath CreateRoundedRectanglePath(Rectangle rect, int cornerRadius)
{
GraphicsPath roundedRect = new GraphicsPath();
roundedRect.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);
roundedRect.AddLine(rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius * 2, rect.Y);
roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2-1, rect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);
roundedRect.AddLine(rect.Right, rect.Y + cornerRadius * 2, rect.Right, rect.Y + rect.Height - cornerRadius * 2);
roundedRect.AddArc(rect.X + rect.Width - cornerRadius * 2-1, rect.Y + rect.Height - cornerRadius * 2-1, cornerRadius * 2, cornerRadius * 2, 0, 90);
roundedRect.AddLine(rect.Right - cornerRadius * 2, rect.Bottom, rect.X + cornerRadius * 2, rect.Bottom);
roundedRect.AddArc(rect.X, rect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);
roundedRect.AddLine(rect.X, rect.Bottom - cornerRadius * 2, rect.X, rect.Y + cornerRadius * 2);
roundedRect.CloseFigure();
return roundedRect;
}
总结
重点是如何利用GDI+的绘画函数,以及一些交互逻辑,如哪里有错误的可以指出来,或有好的意见欢迎提出来一起讨论,谢谢。