从头开始教你创建一个自定义可视化的Winows Form控件(Divider Panel)--For Begnners

Divider Panel- 从头开始教你创建一个自定义可视化的Winows Form 控件
- For Beginners
系统:WindowsXP    P42.2G   内存:512MB
环境:Visual Studio.NET 2003 语言:C#
                                                                                                                     源码下载
 
说明: 参考原文的主线,部分翻译并加了很多个人见解,希望给初学者带来帮助,如在学习这篇文章的时候有什么问题,欢迎提问,我会尽力给大家解决
 
首先看看完成之后的效果:
 
介绍
在这个向导中我们将从开始创造一个可以在.Net ToolBox中使用的Divider Palel控件;控件是很简单的,从Palel继承,增加了可以选择边框外观和边界的属性
 
跟着我的步骤一步一步完成这个控件,你可以学习到:
1.如何继承一个类
2.如何创建自定义的属性
3.如何重载基类的方法
4.如何使用属性的注释
5.如何为你的可视化控件创建自己的图标
6.如何创建一个简单的设计类
7.如何把你的控件整合到.NET IDE的ToolBox中去
 
在这个控件的完成过程中,还将告诉大家一些使用Visual Studio 为我们提供的小捷径,提高我们的效率,相信大家会有所收获,废话不多说,下面正式开始
 
第一步:创建一个空白解决方案
Image1.gif
   为什么我们要创建一个空的解决方案,而不是用向导直接生成一个类库工程呢?相信很多人会有这样的疑问。好听我一一道来:在这样的一个空的解决方案中,我们可以添加多个复合的工程,也就是说除了我们的类库工程,我们还可以添加一个测试用的工程,在不同的工程中测试我们的控件,这样还有点好处就是能方便的使用共享的资源。这是个很好的编程习惯,希望大家能学会用。
 
第二步:添加一个 Windows 控件库工程

      Image2.gif
      #
在添加工程的对话框中选择Windows控件库工程,工程名为 DividerPanel
 
可以看到向导自动为我们生成了一个 UserControl1.cs文件,我们不需要它,选择该文件,删除它,接着我们添加一个我们自己需要的类
Image3.gif
      
      #
在添加类的对话框中输入 DividerPanel.cs作为类名
 
第三步:从现有类继承
继承机制使得面向对象编程如此强大,面向对象已经是现代软件开发的主力了,当然现在还有更新的一些其他编程思想必如:面向方面……
当我们从一个现有类继承的时候,我们自动的获取了基类的一些功能和特性,我们还能让我们的子类具有更特别的属性,具体讲就是我们可以添加新的属性,新的方法,或者是重载父类的方法。
WindowsForm 的很多控件都需要从 System.Windows.Forms.Control 继承, Control 这个基类抽象了很多 .NET FrameWork 支持的公共的属性和方法
说了这么多继承机制,其实要把你的类继承自某一个类的代码是非常简单的:
public class DividerPanel : System.Windows.Forms.Panel
{
}
现在我们的类就具有了 Panel 类的公共属性和方法,我们接下来要做到,就是让我们的类具备我们需要的特性(重载父类的方法 or 添加新的特性)
 
第四步:添加属性和访问器
       我们准备添加两个属性: BorderSideBorder3Dstyle
    BorderSide :获取从 System.Windows.Forms.Border3DSide enumeration(枚举)的一个引用
Border3Dstyle获取从 System.Windows.Forms.Border3DStyle enumeration(枚举)的一个引用
这里给出我们创建属性的最好的方法:
创建两个 Private 的变量,供类里面的方法访问使用
创建两个 Public 的访问器,供外部类访问我们的控件的属性

 

 1
 2
 3 //  This system of private properties with public accessors is a
 4 //  best practice coding style.
 5 //  Note that our private properties are in camelCasing -
 6 //  the first letter is lower case, and additional word 
 7 //  boundaries are capitalized.
 8
 9 private  System.Windows.Forms.Border3DSide borderSide;
10 private  System.Windows.Forms.Border3DStyle border3DStyle;
11
12 //  Next we have our public accessors, Note that for public accessors
13 //  we use PascalCasing - the first letter is capitalized and additional
14 //  word boundaries are also capitalized.
15
16 public  System.Windows.Forms.Border3DSide BorderSide
17 {
18    get return this.borderSide; }
19    set
20    {
21        ifthis.borderSide != value )
22        {
23            this.borderSide = value;
24            this.Invalidate();
25        }

26    }

27}

28
29 public  System.Windows.Forms.Border3DStyle Border3DStyle
30 {
31    get return this.border3DStyle; }
32    set
33    {
34        ifthis.border3DStyle != value )
35        {
36            this.border3DStyle = value;
37            this.Invalidate();
38        }

39    }

40}

41

 

 
注意:添加变量类型应该尽量使用完全路径,这是一个好的编程习惯大家应该养成;
就像这样:(private System.Windows.Forms.Border3DSide borderSide;)
 
接下来说说我们的公共属性访问器,我们的两个公共属性都用了Get和Set访问器,表示是可读可写的属性
Set属性访问器,我们先检查当前值是否等于要设置的值,如果不同在修改,然后调用this.Invalidate()方法;
注意:Invalidate()这个方法的作用是使我们的控件重绘,也就是支持可视化的原理,也就是这么简单的一句话。
 
这里再给大家介绍一点小知识
1.              大家应该养成良好的编码规范,就拿对象命名来说,很多人习惯了使用其他语言的命名规则来命名C#的变量,例如他就把我们的 borderSide 命名为     m_ BorderSide , 虽然这样看来也没什么不妥之处,但是当你使用 this.*** 智能感应机制的时候,问题来了,他就不智能,大家不信可以试一试,既然这个 IDE 为我们提供了如此方便快捷的方法,能提高很多效率,为何不用呢,我想没有人跟自己过不去。
2.              还有一点小技巧,当你输入你的变量的时候,比如我们的 borderSide 这个变量,你不必全部输入,当你输入 bor 还没有输完的时候,按下 Alt 键加方向右键,你就会奇迹般的发现你的变量 borderSide 已经出现在屏幕上了,这对初学者来说是个神奇的功能吧……
      
3.              定义的变量要直观的表示它的含义
4.              通常在构造函数中为我们的变量赋初值,还有其他的初始化工作通常也是在构造函数中完成
 
好了继续我们的程序,现在我们的构造函数应该如下了

 

 1 //  This is the Constructor for our class. Any private variables 
 2 //  we have defined should have their initial values set here. It 
 3 //  is good practice to always initialize every variable to a specific 
 4 //  value, rather then leaving it as an inferred value. For example, 
 5 //  all bool's should be set to false rather than leaving them as an 
 6 //  inferred false, and any objects referenced that are initially null 
 7 //  should be explicitly set to null. (eg. myObject = null)
 8
 9 public  DividerPanel()
10 {
11    // Set default values for our control's properties
12    this.borderSide = System.Windows.Forms.Border3DSide.All;
13    this.border3DStyle = System.Windows.Forms.Border3DStyle.Etched;
14}

15

 

第五步:添加重载的方法
       在标签页选择类视图,效果差不多如下图所示
Image4.gif
   接着找到OnPaint方法,再其上面右击,选择添加重写方法,效果如下图所示
Image5.gif
   我们重写后的代码

 

 1 protected  override  void  OnPaint(System.Windows.Forms.PaintEventArgs e)
 2 {
 3    // allow normal control painting to occur first
 4    base.OnPaint(e);
 5
 6    // add our custom border
 7    System.Windows.Forms.ControlPaint.DrawBorder3D (
 8        e.Graphics,
 9        this.ClientRectangle,
10        this.border3DStyle,
11        this.borderSide );
12}

13

 

下面解说上面代码的意义:
base.OnPaint(e) 调用基类的 OnPaint 函数,它可以帮我们完成很多繁琐的控件绘制工作,当基类的控件绘制完成之后我们接着调用 System.Windows.Forms.ControlPaint.DrawBorder3D ()绘图函数,在 Panel 的上面绘制我们自定义的边框样式,参数就是我们先前定义的样式
另外给大家个小提醒吧 System.Windows.Forms.ControlPaint. 值得你好好研究,它提供了很多静态的方法,用来 windows 样式的控件,比如 Button CheckBoxes, RadioButtons, Grids……
到此为止我们的控件似乎已经完成了,但是不能高兴得太早,距离成功我们还有很多的事情要做呢。
 
第六步:添加属性描述和文件说明
       为了使我们的控件和ToolBox里面提供的没有多大区别,我们要做得更加完善,就像下图所示,对我们的属性要有描述和支持
Image6.gif
   这里还有一点小的技巧,当你在一个函数前面输入“///”的时候,VS 2003自动为你产生一个描述的格式,它自动把函数参数什么的都搞好了,你需要做的只是添加必要的说明。大家试一下便知道。
先看我们的代码,然后我再一一分析,修改之后的代码如下:
 

 

 1 /// <summary>
 2/// Specifies the sides of the panel to apply a three-dimensional border to.
 3/// </summary>

 4 [Bindable( true ), Category( " Border Options " ), 
 5 DefaultValue(System.Windows.Forms.Border3DSide.All),
 6 Description( " Specifies the sides of the panel to apply a 
 7 three - dimensional border to. " )]
 8 public  System.Windows.Forms.Border3DSide BorderSide
 9 {
10    get return this.borderSide; }
11    set
12    {
13        ifthis.borderSide != value )
14        {
15            this.borderSide = value;
16            this.Invalidate();
17        }

18    }

19}

20
21 /// <summary>
22/// Specifies the style of the three-dimensional border.
23/// </summary>

24 [Bindable( true ), Category( " Border Options " ), 
25 DefaultValue(System.Windows.Forms.Border3DStyle.Etched),
26 Description( " Specifies the style of the three-dimensional border. " )]
27 public  System.Windows.Forms.Border3DStyle Border3DStyle
28 {
29    get return this.border3DStyle; }
30    set
31    {
32        ifthis.border3DStyle != value )
33        {
34            this.border3DStyle = value;
35            this.Invalidate();
36        }

37    }

38}

39

 

Bindable(true) 把这个属性设置为True,可以使你的设计器能捕获属性变化的消息,这就是在设计期你能预览效果的原因
Category("Border Options") 属性的分组,很简单,看上面一个图,我们直观的看到Broder3Dstyle和BroderSize在Border Options这个组里面
DefaultValue(System.Windows.Forms.Border3dSide.All) 设置该属性的默认值,从上面的图我们也能直观看出来,Broder3Dstyle使用默认属性,BroderSize使用修改的属性,它被高亮显示了(就是看到Top是加粗的)
Description("Specifies the sides of the panel to apply a three-dimensional border to.")这就更简单了,图中最下面显示的描述,对这个属性你想怎么描述,写这就行了
 
第七步:添加ToolBox 支持
       这一步相当简单,添加一个位图文件,文件名为DividerPanel.bmp,右击属性选择编译类型为 嵌入式资源(这点很重要),位图大小16*16,采用16位色
       Image7.gif
自己想把这个图画成啥样都行的,下面只是个简单的示范
Image8.gif
   最后添加代码是ToolBox能识别出控件的图标资源
[ToolboxItem(true)]
[ToolboxBitmap(typeof(DividerPanel))]
public class DividerPanel : System.Windows.Forms.Panel
{
}
说明:第一行是说让ToolBox支持我们的控件,虽然默认这个属性是true但还是鼓励大家把代码写出来,这样更加直观
第二行告诉编译器,DividerPanel.bmp是控件的图标文件
 
第八步:添加一个简单的设计类
       右击我们的工程,选择添加类,类名为 DividerPanelDesigner.cs
       为我们的类添加引用,System.Design;,你会发现当你准备使用using System.**的时候,那个点,点不出来我们
from:http://www.cnblogs.com/jht/archive/2005/08/10/211650.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值