一、简单回顾
在上一篇中,介绍了如何去扩展WinFrom现有控件来实现一个新的控件。
扩展控件的主要方法就是根据需求,提取所需控件的相关特定的属性和方法,对属性和方法进行扩展,以此来实现新的控件。在扩展控件开发过程中,需要实现OnPaint事件代码或者重写WndProc回调函数方法。
二、扩展GroupBox控件
在本节中,主要在WinFrom窗体控件GroupBox基础上扩展一个新的控件。新控件需要实现:
1、GroupBox的边框颜色可以自行设置;
2、GroupBox可以设置边框的为圆角;
3、设置GroupBox标题在控件中的位置。
4、设置GroupBox标题的字体和颜色。
具体实现步骤Panel扩展一样,直接看具体的代码,代码如下:
- public class GroupBoxEx : GroupBox
- {
- private Font _titleFont = new Font("宋体", 10, FontStyle.Regular);
- private Color _titleColor = Color.Green;
- private Color _borderColor = Color.FromArgb(23, 169, 254);
- private int _radius = 10;
- private int _tiltePos =10;
- private const int WM_ERASEBKGND = 0x0014;
- private const int WM_PAINT = 0xF;
- public GroupBoxEx()
- : base()
- {
- }
- [DefaultValue(typeof(Color), "23, 169, 254"), Description("控件边框颜色")]
- public Color BorderColor
- {
- get { return _borderColor; }
- set
- {
- _borderColor = value;
- base.Invalidate();
- }
- }
- [DefaultValue(typeof(Color), "Green"), Description("标题颜色")]
- public Color TitleColor
- {
- get { return _titleColor; }
- set
- {
- _titleColor = value;
- base.Invalidate();
- }
- }
- [DefaultValue(typeof(Font), ""), Description("标题字体设置")]
- public Font TitleFont
- {
- get { return _titleFont; }
- set
- {
- _titleFont = value;
- base.Invalidate();
- }
- }
- [DefaultValue(typeof(int), "30"), Description("圆角弧度大小")]
- public int Radius
- {
- get { return _radius; }
- set
- {
- _radius = value;
- base.Invalidate();
- }
- }
- [DefaultValue(typeof(int), "10"), Description("标题位置")]
- public int TiltePos
- {
- get { return _tiltePos; }
- set
- {
- _tiltePos = value;
- base.Invalidate();
- }
- }
- protected override void WndProc(ref Message m)
- {
- try
- {
- base.WndProc(ref m);
- if (m.Msg == WM_PAINT)
- {
- if (this.Radius > 0)
- {
- using (Graphics g = Graphics.FromHwnd(this.Handle))
- {
- Rectangle r = new Rectangle();
- r.Width = this.Width;
- r.Height = this.Height;
- DrawBorder(g, r, this.Radius);
- }
- }
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
- }
- private void DrawBorder(Graphics g, Rectangle rect, int radius)
- {
- rect.Width -= 1;
- rect.Height -= 1;
- using (Pen pen = new Pen(this.BorderColor))
- {
- g.Clear(this.BackColor);
- g.DrawString(this.Text, this.TitleFont, new SolidBrush(this.TitleColor), radius + this.TiltePos, 0);
- g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
- GraphicsPath path = new GraphicsPath();
- float height = g.MeasureString(this.Text, this.TitleFont).Height / 2;
- float width = g.MeasureString(this.Text, this.TitleFont).Width;
- path.AddArc(rect.X, rect.Y + height, radius, radius, 180, 90);//左上角弧线
- path.AddLine(radius, rect.Y + height, radius + this.TiltePos, rect.Y + height);
- path.StartFigure();
- path.AddLine(radius + this.TiltePos + width, rect.Y + height, rect.Right - radius, rect.Y + height);
- path.AddArc(rect.Right - radius, rect.Y + height, radius, radius, 270, 90);//右上角弧线
- path.AddArc(rect.Right - radius, rect.Bottom - radius, radius, radius, 0, 90);
- path.AddArc(rect.X, rect.Bottom - radius, radius, radius, 90, 90);
- path.StartFigure();
- path.AddArc(rect.X, rect.Y + height, radius, radius, -90, -90);//左上角弧线
- path.AddArc(rect.X, rect.Bottom - radius, radius, radius, -180, -90);
- g.DrawPath(pen, path);
- }
- }
- }
编码完成之后,控件效果如下:
1、在扩展GroupBox控件中,为了实现上述需求,扩展了5个自定义属性,编码完成,编译之后,控件的属性多了以下项,如图所示:
2、控件运行之后效果,如下:
至此,扩展控件完成,已经达到预期想要的效果,呵呵~~
三、关联知识补遗
1、如何给自定义控件属性设置默认值和功能提示?
在属性之前,添加此行代码:[DefaultValue(typeof(Color), "23, 169, 254"),Description("控件边框颜色")]
DefaultValue 属于System.ComponentModel.DefaultValueAttribute类中,设置属性的初始值。
Description 用于描述属性。
设置属性是否在控件属性框中显示,可在属性前加[Browsable(false)],这样就能隐藏属性在属性栏中的显示。
2、GraphicsPath类介绍
GraphicsPath类提供了一系列的绘制图形的方法,比如AddArc、AddLine等等,可以绘制各种曲线 。可以通过使用 CloseFigure() 方法显式闭合一个图形,通过StartFigure()方法创建一个新的图像。
(1)、GraphicsPath 对象存储一系列直线和贝塞尔样条。可以将多种类型的曲线(椭圆、弧形和基数样条)添加到路径,但在存储到路径之前,各种曲线都被转换为贝塞尔样条。
(2)、应用程序使用路径来绘制形状的轮廓、填充形状内部和创建剪辑区域。
(3)、路径可由任意数目的图形(子路径)组成。每一图形都是由一系列相互连接的直线和曲线或几何形状基元构成的。图形的起始点是相互连接的一系列直线和曲线中的第一点。终结点是该序列中的最后一点。
(4)、图形具有方向,方向描述在起始点和终结点之间绘制直线段和曲线段的方式。方向按将直线和曲线添加到图形的顺序定义,或者按几何形状基元定义。方向用来确定剪辑和填充的路径内部。
原文地址:http://www.itbobo.com/winfrom-groupbox.html