由于项目需求,需要重写Winform Button 控件,达到用户体验. 在网上查了许多资料,其中有参考水晶按钮. 最后效果,如下图
首先有定义几个枚举对象:
1 private enum MouseAction
2 {
3 Leave,
4 Over,
5 Click
6 }
7 /// <summary>
8 /// 颜色渐变方式
9 /// </summary>
10 private enum GradualMethod
11 {
12 UpToDown,
13 LeftToRight,
14 LeftUpToRightDown,
15 RightUpToLeftDown
16 }
2 {
3 Leave,
4 Over,
5 Click
6 }
7 /// <summary>
8 /// 颜色渐变方式
9 /// </summary>
10 private enum GradualMethod
11 {
12 UpToDown,
13 LeftToRight,
14 LeftUpToRightDown,
15 RightUpToLeftDown
16 }
然后定义渐变色属性:
1 /// <summary>
2 /// 第一渐变颜色
3 /// </summary>
4 public Color FirstGradualColor
5 {
6 get
7 {
8 return FirstColor;
9 }
10 set
11 {
12 FirstColor = value;
13 }
14 }
15 /// <summary>
16 /// 第二渐变颜色
17 /// </summary>
18 public Color SecondGradualColor
19 {
20 get
21 {
22 return SecondColor;
23 }
24 set
25 {
26 SecondColor = value;
27 }
28 }
2 /// 第一渐变颜色
3 /// </summary>
4 public Color FirstGradualColor
5 {
6 get
7 {
8 return FirstColor;
9 }
10 set
11 {
12 FirstColor = value;
13 }
14 }
15 /// <summary>
16 /// 第二渐变颜色
17 /// </summary>
18 public Color SecondGradualColor
19 {
20 get
21 {
22 return SecondColor;
23 }
24 set
25 {
26 SecondColor = value;
27 }
28 }
最后在Onpaint事件中处理相应该的重绘工作. 代码如下:
1 protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
2 {
3 int r = 10;
4 int BtnOffSet = 0;
5 Color FColor = Color.FromArgb(245, 245, 245);
6 Color SColor = Color.FromArgb(180, 175, 190);
7 Color TempFColor = this.FirstColor;
8 Color TempSColor = this.SecondColor;
9 int offsetwidth = this.Width / 50;
10 switch (MAction)
11 {
12 case MouseAction.Click:
13 BtnOffSet = 2;
14 break;
15 case MouseAction.Leave:
16 BtnOffSet = 0;
17 TempFColor = FirstColor;
18 TempSColor = SecondColor;
19 break;
20 case MouseAction.Over:
21 TempFColor = FColor;
22 TempSColor = SColor;
23 break;
24 }
25 Rectangle rc = new Rectangle(BtnOffSet, BtnOffSet, this.ClientSize.Width-1 , this.ClientSize.Height-1 );
26 int x = rc.X, y = rc.Y, w = rc.Width, h = rc.Height;
27 GraphicsPath path = new GraphicsPath();
28 path.AddArc(x, y, r, r, 180, 90);
29 path.AddArc(x + w - r, y, r, r, 270, 90);
30 path.AddArc(x + w - r, y + h - r, r, r, 0, 90);
31 path.AddArc(x, y + h - r, r, r, 90, 90);
32 path.CloseFigure();
33 this.Region = new Region(path);
34 LinearGradientBrush b = null;
35 switch (GradualM)
36 {
37 case GradualMethod.UpToDown:
38 b = new LinearGradientBrush(rc, TempFColor, TempSColor, LinearGradientMode.Vertical);
39 break;
40 case GradualMethod.RightUpToLeftDown:
41 b = new LinearGradientBrush(rc, TempFColor, TempSColor, LinearGradientMode.BackwardDiagonal);
42 break;
43 case GradualMethod.LeftUpToRightDown:
44 b = new LinearGradientBrush(rc, TempFColor, TempSColor, LinearGradientMode.ForwardDiagonal);
45 break;
46 case GradualMethod.LeftToRight:
47 b = new LinearGradientBrush(rc, TempFColor, TempSColor, LinearGradientMode.Horizontal);
48 break;
49 }
50 e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
51 e.Graphics.FillPath(b, path);
52 e.Graphics.DrawPath(new Pen(Color.Gray, 3), path);
53 StringFormat drawFormat = new StringFormat();
54 drawFormat.FormatFlags = StringFormatFlags.DisplayFormatControl;
55 drawFormat.LineAlignment = StringAlignment.Center;
56 drawFormat.Alignment = System.Drawing.StringAlignment.Center;
57 e.Graphics.DrawString(this.Text, this.Font, new LinearGradientBrush(this.ClientRectangle, Color.Black, Color.Black, LinearGradientMode.Vertical), rc, drawFormat);
58 b.Dispose();
59 }
60 protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs mevent)
61 {
62 MAction = MouseAction.Click;
63 this.Invalidate(false);
64 base.OnMouseDown(mevent);
65 }
66 protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs mevent)
67 {
68 MAction = MouseAction.Over;
69 this.Invalidate(false);
70 base.OnMouseUp(mevent);
71 }
72 protected override void OnMouseEnter(EventArgs e)
73 {
74 MAction = MouseAction.Over;
75 this.Invalidate(false);
76 base.OnMouseEnter(e);
77 }
78 protected override void OnNotifyMessage(System.Windows.Forms.Message m)
79 {
80 base.OnNotifyMessage(m);
81 }
82 protected override void OnMouseLeave(EventArgs e)
83 {
84 MAction = MouseAction.Leave;
85 this.Invalidate(false);
86 base.OnMouseLeave(e);
87 }
88 protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs pevent)
89 {
90 pevent.Graphics.Clear(Color.Wheat);
91 }
3 int r = 10;
4 int BtnOffSet = 0;
5 Color FColor = Color.FromArgb(245, 245, 245);
6 Color SColor = Color.FromArgb(180, 175, 190);
7 Color TempFColor = this.FirstColor;
8 Color TempSColor = this.SecondColor;
9 int offsetwidth = this.Width / 50;
10 switch (MAction)
11 {
12 case MouseAction.Click:
13 BtnOffSet = 2;
14 break;
15 case MouseAction.Leave:
16 BtnOffSet = 0;
17 TempFColor = FirstColor;
18 TempSColor = SecondColor;
19 break;
20 case MouseAction.Over:
21 TempFColor = FColor;
22 TempSColor = SColor;
23 break;
24 }
25 Rectangle rc = new Rectangle(BtnOffSet, BtnOffSet, this.ClientSize.Width-1 , this.ClientSize.Height-1 );
26 int x = rc.X, y = rc.Y, w = rc.Width, h = rc.Height;
27 GraphicsPath path = new GraphicsPath();
28 path.AddArc(x, y, r, r, 180, 90);
29 path.AddArc(x + w - r, y, r, r, 270, 90);
30 path.AddArc(x + w - r, y + h - r, r, r, 0, 90);
31 path.AddArc(x, y + h - r, r, r, 90, 90);
32 path.CloseFigure();
33 this.Region = new Region(path);
34 LinearGradientBrush b = null;
35 switch (GradualM)
36 {
37 case GradualMethod.UpToDown:
38 b = new LinearGradientBrush(rc, TempFColor, TempSColor, LinearGradientMode.Vertical);
39 break;
40 case GradualMethod.RightUpToLeftDown:
41 b = new LinearGradientBrush(rc, TempFColor, TempSColor, LinearGradientMode.BackwardDiagonal);
42 break;
43 case GradualMethod.LeftUpToRightDown:
44 b = new LinearGradientBrush(rc, TempFColor, TempSColor, LinearGradientMode.ForwardDiagonal);
45 break;
46 case GradualMethod.LeftToRight:
47 b = new LinearGradientBrush(rc, TempFColor, TempSColor, LinearGradientMode.Horizontal);
48 break;
49 }
50 e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
51 e.Graphics.FillPath(b, path);
52 e.Graphics.DrawPath(new Pen(Color.Gray, 3), path);
53 StringFormat drawFormat = new StringFormat();
54 drawFormat.FormatFlags = StringFormatFlags.DisplayFormatControl;
55 drawFormat.LineAlignment = StringAlignment.Center;
56 drawFormat.Alignment = System.Drawing.StringAlignment.Center;
57 e.Graphics.DrawString(this.Text, this.Font, new LinearGradientBrush(this.ClientRectangle, Color.Black, Color.Black, LinearGradientMode.Vertical), rc, drawFormat);
58 b.Dispose();
59 }
60 protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs mevent)
61 {
62 MAction = MouseAction.Click;
63 this.Invalidate(false);
64 base.OnMouseDown(mevent);
65 }
66 protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs mevent)
67 {
68 MAction = MouseAction.Over;
69 this.Invalidate(false);
70 base.OnMouseUp(mevent);
71 }
72 protected override void OnMouseEnter(EventArgs e)
73 {
74 MAction = MouseAction.Over;
75 this.Invalidate(false);
76 base.OnMouseEnter(e);
77 }
78 protected override void OnNotifyMessage(System.Windows.Forms.Message m)
79 {
80 base.OnNotifyMessage(m);
81 }
82 protected override void OnMouseLeave(EventArgs e)
83 {
84 MAction = MouseAction.Leave;
85 this.Invalidate(false);
86 base.OnMouseLeave(e);
87 }
88 protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs pevent)
89 {
90 pevent.Graphics.Clear(Color.Wheat);
91 }
92 }
以上为主要实现的代码,另外,在处理中还对Mouse动作有作处理. 在此 不多说. 其实在整个重写过程中. 主要有以下几步:
1:绘制按钮的区域(圆形,矩形等你能想到的图形)
2:填充区域颜色或渐变色. 以及边框
3:按钮的字体