前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
NuGet
Install-Package HZH_Controls
目录
https://blog.csdn.net/kwwwvagaa/article/details/100586547
用处及效果
准备工作
这个是基于(四十一)c#Winform自定义控件-进度条 扩展的,如果你还没有了解,请先移步了解一下
开始
添加一个用户控件,命名UCProcessLineExt
属性
1 [Description("值变更事件"), Category("自定义")]
2 public event EventHandler ValueChanged;
3
4 [Description("当前属性"), Category("自定义")]
5 public int Value
6 {
7 set
8 {
9 ucProcessLine1.Value = value;
10 Refresh();
11 }
12 get
13 {
14 return ucProcessLine1.Value;
15 }
16 }
17
18
19
20 [Description("最大值"), Category("自定义")]
21 public int MaxValue
22 {
23 get { return ucProcessLine1.MaxValue; }
24 set
25 {
26 ucProcessLine1.MaxValue = value;
27 Refresh();
28 }
29 }
30
31
32 [Description("值进度条颜色"), Category("自定义")]
33 public Color ValueColor
34 {
35 get { return ucProcessLine1.ValueColor; }
36 set
37 {
38 ucProcessLine1.ValueColor = value;
39 Refresh();
40 }
41 }
42
43
44 [Description("值背景色"), Category("自定义")]
45 public Color ValueBGColor
46 {
47 get { return ucProcessLine1.ValueBGColor; }
48 set
49 {
50 ucProcessLine1.ValueBGColor = value;
51 Refresh();
52 }
53 }
54
55
56 [Description("边框颜色"), Category("自定义")]
57 public Color BorderColor
58 {
59 get { return ucProcessLine1.BorderColor; }
60 set
61 {
62 ucProcessLine1.BorderColor = value;
63 Refresh();
64 }
65 }
66
67 [Description("值字体"), Category("自定义")]
68 public override Font Font
69 {
70 get
71 {
72 return ucProcessLine1.Font;
73 }
74 set
75 {
76 ucProcessLine1.Font = value;
77 Refresh();
78 }
79 }
80
81 [Description("值块颜色"), Category("自定义")]
82 public override System.Drawing.Color ForeColor
83 {
84 get
85 {
86 return base.ForeColor;
87 }
88 set
89 {
90 base.ForeColor = value;
91 Refresh();
92 }
93 }
重绘
1 protected override void OnPaint(PaintEventArgs e)
2 {
3 base.OnPaint(e);
4 e.Graphics.SetGDIHigh();
5 float fltIndex = (float)this.ucProcessLine1.Value / (float)this.ucProcessLine1.MaxValue;
6
7 int x = (int)(fltIndex * this.ucProcessLine1.Width + this.ucProcessLine1.Location.X - 15) - 2;
8 GraphicsPath path = new GraphicsPath();
9 Rectangle rect = new Rectangle(x, 1, 30, 20);
10 int cornerRadius = 2;
11 path.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);
12 path.AddLine(rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius * 2, rect.Y);
13 path.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);
14 path.AddLine(rect.Right, rect.Y + cornerRadius * 2, rect.Right, rect.Y + rect.Height - cornerRadius * 2);
15 path.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y + rect.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);
16 path.AddLine(rect.Right - cornerRadius * 2, rect.Bottom, rect.Right - cornerRadius * 2 - 5, rect.Bottom);//下
17 path.AddLine(rect.Right - cornerRadius * 2 - 5, 21, x + 15, ucProcessLine1.Location.Y);
18 path.AddLine(x + 15, ucProcessLine1.Location.Y, rect.X + cornerRadius * 2 + 5, 21);
19 path.AddLine(rect.X + cornerRadius * 2 + 5, 20, rect.X + cornerRadius * 2, rect.Bottom);//下
20 path.AddArc(rect.X, rect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);
21 path.AddLine(rect.X, rect.Bottom - cornerRadius * 2, rect.X, rect.Y + cornerRadius * 2);//上
22 path.CloseFigure();
23
24 e.Graphics.FillPath(new SolidBrush(ForeColor), path);
25
26 string strValue = ((float)Value / (float)MaxValue).ToString("0%");
27 System.Drawing.SizeF sizeF = e.Graphics.MeasureString(strValue, Font);
28 e.Graphics.DrawString(strValue, Font, new SolidBrush(Color.White), new PointF(x + (30 - sizeF.Width) / 2+1, (20 - sizeF.Height) / 2 + 1));
29 }
全部代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace HZH_Controls.Controls
{
public partial class UCProcessLineExt : UserControl
{
[Description("值变更事件"), Category("自定义")]
public event EventHandler ValueChanged;
[Description("当前属性"), Category("自定义")]
public int Value
{
set
{
ucProcessLine1.Value = value;
Refresh();
}
get
{
return ucProcessLine1.Value;
}
}
[Description("最大值"), Category("自定义")]
public int MaxValue
{
get { return ucProcessLine1.MaxValue; }
set
{
ucProcessLine1.MaxValue = value;
Refresh();
}
}
[Description("值进度条颜色"), Category("自定义")]
public Color ValueColor
{
get { return ucProcessLine1.ValueColor; }
set
{
ucProcessLine1.ValueColor = value;
Refresh();
}
}
[Description("值背景色"), Category("自定义")]
public Color ValueBGColor
{
get { return ucProcessLine1.ValueBGColor; }
set
{
ucProcessLine1.ValueBGColor = value;
Refresh();
}
}
[Description("边框颜色"), Category("自定义")]
public Color BorderColor
{
get { return ucProcessLine1.BorderColor; }
set
{
ucProcessLine1.BorderColor = value;
Refresh();
}
}
[Description("值字体"), Category("自定义")]
public override Font Font
{
get
{
return ucProcessLine1.Font;
}
set
{
ucProcessLine1.Font = value;
Refresh();
}
}
[Description("值块颜色"), Category("自定义")]
public override System.Drawing.Color ForeColor
{
get
{
return base.ForeColor;
}
set
{
base.ForeColor = value;
Refresh();
}
}
public UCProcessLineExt()
{
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.SetStyle(ControlStyles.UserPaint, true);
ucProcessLine1.ValueChanged += ucProcessLine1_ValueChanged;
}
void ucProcessLine1_ValueChanged(object sender, EventArgs e)
{
if (ValueChanged != null)
{
ValueChanged(this, e);
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.SetGDIHigh();
float fltIndex = (float)this.ucProcessLine1.Value / (float)this.ucProcessLine1.MaxValue;
int x = (int)(fltIndex * this.ucProcessLine1.Width + this.ucProcessLine1.Location.X - 15) - 2;
GraphicsPath path = new GraphicsPath();
Rectangle rect = new Rectangle(x, 1, 30, 20);
int cornerRadius = 2;
path.AddArc(rect.X, rect.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);
path.AddLine(rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius * 2, rect.Y);
path.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);
path.AddLine(rect.Right, rect.Y + cornerRadius * 2, rect.Right, rect.Y + rect.Height - cornerRadius * 2);
path.AddArc(rect.X + rect.Width - cornerRadius * 2, rect.Y + rect.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);
path.AddLine(rect.Right - cornerRadius * 2, rect.Bottom, rect.Right - cornerRadius * 2 - 5, rect.Bottom);//下
path.AddLine(rect.Right - cornerRadius * 2 - 5, 21, x + 15, ucProcessLine1.Location.Y);
path.AddLine(x + 15, ucProcessLine1.Location.Y, rect.X + cornerRadius * 2 + 5, 21);
path.AddLine(rect.X + cornerRadius * 2 + 5, 20, rect.X + cornerRadius * 2, rect.Bottom);//下
path.AddArc(rect.X, rect.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);
path.AddLine(rect.X, rect.Bottom - cornerRadius * 2, rect.X, rect.Y + cornerRadius * 2);//上
path.CloseFigure();
e.Graphics.FillPath(new SolidBrush(ForeColor), path);
string strValue = ((float)Value / (float)MaxValue).ToString("0%");
System.Drawing.SizeF sizeF = e.Graphics.MeasureString(strValue, Font);
e.Graphics.DrawString(strValue, Font, new SolidBrush(Color.White), new PointF(x + (30 - sizeF.Width) / 2+1, (20 - sizeF.Height) / 2 + 1));
}
}
}
namespace HZH_Controls.Controls
{
partial class UCProcessLineExt
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.ucProcessLine1 = new HZH_Controls.Controls.UCProcessLine();
this.SuspendLayout();
//
// ucProcessLine1
//
this.ucProcessLine1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.ucProcessLine1.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(192)))), ((int)(((byte)(192)))));
this.ucProcessLine1.Font = new System.Drawing.Font("Arial Unicode MS", 10F);
this.ucProcessLine1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(77)))), ((int)(((byte)(59)))));
this.ucProcessLine1.Location = new System.Drawing.Point(18, 33);
this.ucProcessLine1.MaxValue = 100;
this.ucProcessLine1.Name = "ucProcessLine1";
this.ucProcessLine1.Size = new System.Drawing.Size(399, 16);
this.ucProcessLine1.TabIndex = 0;
this.ucProcessLine1.Text = "ucProcessLine1";
this.ucProcessLine1.Value = 0;
this.ucProcessLine1.ValueBGColor = System.Drawing.Color.White;
this.ucProcessLine1.ValueColor = System.Drawing.Color.FromArgb(((int)(((byte)(73)))), ((int)(((byte)(119)))), ((int)(((byte)(232)))));
this.ucProcessLine1.ValueTextType = HZH_Controls.Controls.ValueTextType.None;
//
// UCProcessLineExt
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackColor = System.Drawing.Color.Transparent;
this.Controls.Add(this.ucProcessLine1);
this.Name = "UCProcessLineExt";
this.Size = new System.Drawing.Size(434, 50);
this.ResumeLayout(false);
}
#endregion
private UCProcessLine ucProcessLine1;
}
}
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧