前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
官网:https://www.hzhcontrols.cn
GitHub:https://github.com/kwwwvagaa/NetWinformControl
如果觉得写的还行,请点个 star 支持一下吧
麻烦博客下方点个【推荐】,谢谢
NuGet
Install-Package HZH_Controls
目录
c#Winform自定义控件-目录_c#winform自定义控件-有图标的按钮-CSDN博客
用处及效果
准备工作
依然是GDI+画的,如果不了解可以百度下先
开始
添加一个枚举,用以控制移动方向
1 public enum RollStyle
2 {
3 LeftToRight,
4 RightToLeft,
5 BackAndForth
6 }
添加一个类UCRollText,继承UserControl
添加几个控制属性
1 public override Font Font
2 {
3 get
4 {
5 return base.Font;
6 }
7 set
8 {
9 base.Font = value;
10 if (!string.IsNullOrEmpty(Text))
11 {
12 Graphics g = this.CreateGraphics();
13 var size = g.MeasureString(Text, this.Font);
14 rectText = new Rectangle(0, (this.Height - rectText.Height) / 2 + 1, (int)size.Width, (int)size.Height);
15 rectText.Y = (this.Height - rectText.Height) / 2 + 1;
16 }
17 }
18 }
19
20 public override Color ForeColor
21 {
22 get
23 {
24 return base.ForeColor;
25 }
26 set
27 {
28 base.ForeColor = value;
29 }
30 }
31
32 public override string Text
33 {
34 get
35 {
36 return base.Text;
37 }
38 set
39 {
40 base.Text = value;
41 if (!string.IsNullOrEmpty(value))
42 {
43 Graphics g = this.CreateGraphics();
44 var size = g.MeasureString(value, this.Font);
45 rectText = new Rectangle(0, (this.Height - rectText.Height) / 2 + 1, (int)size.Width, (int)size.Height);
46 }
47 else
48 {
49 rectText = Rectangle.Empty;
50 }
51 }
52 }
53
54 private RollStyle _RollStyle = RollStyle.LeftToRight;
55
56 [Description("滚动样式"), Category("自定义")]
57 public RollStyle RollStyle
58 {
59 get { return _RollStyle; }
60 set
61 {
62 _RollStyle = value;
63 switch (value)
64 {
65 case RollStyle.LeftToRight:
66 m_intdirection = 1;
67 break;
68 case RollStyle.RightToLeft:
69 m_intdirection = -1;
70 break;
71 }
72 }
73 }
74
75 private int _moveStep = 5;
76
77 private int _moveSleepTime = 100;
78
79 [Description("每次滚动间隔时间,越小速度越快"), Category("自定义")]
80 public int MoveSleepTime
81 {
82 get { return _moveSleepTime; }
83 set
84 {
85 if (value <= 0)
86 return;
87
88 _moveSleepTime = value;
89 m_timer.Interval = value;
90 }
91 }
92
93 int m_intdirection = 1;
94
95 Rectangle rectText;
96 Timer m_timer;
构造函数处理一些事情
1 public UCRollText()
2 {
3 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
4 this.SetStyle(ControlStyles.DoubleBuffer, true);
5 this.SetStyle(ControlStyles.ResizeRedraw, true);
6 this.SetStyle(ControlStyles.Selectable, true);
7 this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
8 this.SetStyle(ControlStyles.UserPaint, true);
9
10 this.SizeChanged += UCRollText_SizeChanged;
11 this.Size = new Size(450, 30);
12 Text = "滚动文字";
13 m_timer = new Timer();
14 m_timer.Interval = 100;
15 m_timer.Tick += m_timer_Tick;
16 this.Load += UCRollText_Load;
17 this.VisibleChanged += UCRollText_VisibleChanged;
18 this.ForeColor = Color.FromArgb(255, 77, 59);
19 if (rectText != Rectangle.Empty)
20 {
21 rectText.Y = (this.Height - rectText.Height) / 2 + 1;
22 }
23 }
加载的时候处理一下初始位置
1 void UCRollText_Load(object sender, EventArgs e)
2 {
3 if (_RollStyle == HZH_Controls.Controls.RollStyle.LeftToRight)
4 {
5 m_intdirection = 1;
6 if (rectText != Rectangle.Empty)
7 {
8 rectText.X = -1 * rectText.Width - 1;
9 }
10 }
11 else if (_RollStyle == HZH_Controls.Controls.RollStyle.RightToLeft)
12 {
13 m_intdirection = -1;
14 if (rectText != Rectangle.Empty)
15 {
16 rectText.X = this.Width + rectText.Width + 1;
17 }
18 }
19 else
20 {
21 m_intdirection = 1;
22 if (rectText != Rectangle.Empty)
23 {
24 rectText.X = 0;
25 }
26 }
27 if (rectText != Rectangle.Empty)
28 {
29 rectText.Y = (this.Height - rectText.Height) / 2 + 1;
30 }
31 }
定时器里面处理位置
1 void m_timer_Tick(object sender, EventArgs e)
2 {
3 if (rectText == Rectangle.Empty)
4 return;
5 if (_RollStyle == HZH_Controls.Controls.RollStyle.BackAndForth && rectText.Width >= this.Width)
6 {
7 return;
8 }
9 rectText.X = rectText.X + _moveStep * m_intdirection;
10 if (_RollStyle == HZH_Controls.Controls.RollStyle.BackAndForth)
11 {
12 if (rectText.X <= 0)
13 {
14 m_intdirection = 1;
15 }
16 else if (rectText.Right >= this.Width)
17 {
18 m_intdirection = -1;
19 }
20 }
21 else if (_RollStyle == HZH_Controls.Controls.RollStyle.LeftToRight)
22 {
23 if (rectText.X > this.Width)
24 {
25 rectText.X = -1 * rectText.Width - 1;
26 }
27 }
28 else
29 {
30 if (rectText.Right < 0)
31 {
32 rectText.X = this.Width + rectText.Width + 1;
33 }
34 }
35 Refresh();
36 }
重绘
1 protected override void OnPaint(PaintEventArgs e)
2 {
3 base.OnPaint(e);
4 if (rectText != Rectangle.Empty)
5 {
6 e.Graphics.SetGDIHigh();
7 e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), rectText.Location);
8 }
9 }
完整代码
// 版权所有 黄正辉 交流群:568015492 QQ:623128629
// 文件名称:UCRollText.cs
// 作 者:HZH
// 创建日期:2019-09-03 09:59:12
// 功能描述:UCRollText English:UCRollText
// 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
// 项目地址:https://github.com/kwwwvagaa/NetWinformControl
// 如果你使用了此类,请保留以上说明
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
namespace HZH_Controls.Controls
{
public class UCRollText : UserControl
{
public override Font Font
{
get
{
return base.Font;
}
set
{
base.Font = value;
if (!string.IsNullOrEmpty(Text))
{
Graphics g = this.CreateGraphics();
var size = g.MeasureString(Text, this.Font);
rectText = new Rectangle(0, (this.Height - rectText.Height) / 2 + 1, (int)size.Width, (int)size.Height);
rectText.Y = (this.Height - rectText.Height) / 2 + 1;
}
}
}
public override Color ForeColor
{
get
{
return base.ForeColor;
}
set
{
base.ForeColor = value;
}
}
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
if (!string.IsNullOrEmpty(value))
{
Graphics g = this.CreateGraphics();
var size = g.MeasureString(value, this.Font);
rectText = new Rectangle(0, (this.Height - rectText.Height) / 2 + 1, (int)size.Width, (int)size.Height);
}
else
{
rectText = Rectangle.Empty;
}
}
}
private RollStyle _RollStyle = RollStyle.LeftToRight;
[Description("滚动样式"), Category("自定义")]
public RollStyle RollStyle
{
get { return _RollStyle; }
set
{
_RollStyle = value;
switch (value)
{
case RollStyle.LeftToRight:
m_intdirection = 1;
break;
case RollStyle.RightToLeft:
m_intdirection = -1;
break;
}
}
}
private int _moveStep = 5;
private int _moveSleepTime = 100;
[Description("每次滚动间隔时间,越小速度越快"), Category("自定义")]
public int MoveSleepTime
{
get { return _moveSleepTime; }
set
{
if (value <= 0)
return;
_moveSleepTime = value;
m_timer.Interval = value;
}
}
int m_intdirection = 1;
Rectangle rectText;
Timer m_timer;
public UCRollText()
{
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);
this.SizeChanged += UCRollText_SizeChanged;
this.Size = new Size(450, 30);
Text = "滚动文字";
m_timer = new Timer();
m_timer.Interval = 100;
m_timer.Tick += m_timer_Tick;
this.Load += UCRollText_Load;
this.VisibleChanged += UCRollText_VisibleChanged;
this.ForeColor = Color.FromArgb(255, 77, 59);
if (rectText != Rectangle.Empty)
{
rectText.Y = (this.Height - rectText.Height) / 2 + 1;
}
}
void m_timer_Tick(object sender, EventArgs e)
{
if (rectText == Rectangle.Empty)
return;
if (_RollStyle == HZH_Controls.Controls.RollStyle.BackAndForth && rectText.Width >= this.Width)
{
return;
}
rectText.X = rectText.X + _moveStep * m_intdirection;
if (_RollStyle == HZH_Controls.Controls.RollStyle.BackAndForth)
{
if (rectText.X <= 0)
{
m_intdirection = 1;
}
else if (rectText.Right >= this.Width)
{
m_intdirection = -1;
}
}
else if (_RollStyle == HZH_Controls.Controls.RollStyle.LeftToRight)
{
if (rectText.X > this.Width)
{
rectText.X = -1 * rectText.Width - 1;
}
}
else
{
if (rectText.Right < 0)
{
rectText.X = this.Width + rectText.Width + 1;
}
}
Refresh();
}
void UCRollText_VisibleChanged(object sender, EventArgs e)
{
m_timer.Enabled = this.Visible;
}
void UCRollText_Load(object sender, EventArgs e)
{
if (_RollStyle == HZH_Controls.Controls.RollStyle.LeftToRight)
{
m_intdirection = 1;
if (rectText != Rectangle.Empty)
{
rectText.X = -1 * rectText.Width - 1;
}
}
else if (_RollStyle == HZH_Controls.Controls.RollStyle.RightToLeft)
{
m_intdirection = -1;
if (rectText != Rectangle.Empty)
{
rectText.X = this.Width + rectText.Width + 1;
}
}
else
{
m_intdirection = 1;
if (rectText != Rectangle.Empty)
{
rectText.X = 0;
}
}
if (rectText != Rectangle.Empty)
{
rectText.Y = (this.Height - rectText.Height) / 2 + 1;
}
}
void UCRollText_SizeChanged(object sender, EventArgs e)
{
if (rectText != Rectangle.Empty)
{
rectText.Y = (this.Height - rectText.Height) / 2 + 1;
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (rectText != Rectangle.Empty)
{
e.Graphics.SetGDIHigh();
e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), rectText.Location);
}
}
}
public enum RollStyle
{
LeftToRight,
RightToLeft,
BackAndForth
}
}