本文是基于Windows平台下的dot Net环境上的Form程序,思想可能也适用于其他场合。算是对过去开发经验的总结,保不齐有些内容是胡扯,勿怪。
一.背景介绍
很多时候做winForm程序时,标准控件不能完全满足要求,第三方可能也不太合适,比如收费,这个时候往往需要自己开发一个控件。牛人可能会有所不同, 但我想大多数人的做法无外乎两种:
1.继承已有标准控件类(诸如ListView等),然后增删其功能,使之符合预期(本文重点介绍),称之为拓展控件。
2.直接继承UserControl/Control类,在其上修改,使之满足自己的需要,这个呢大部分应该是追加新机能,称之为复合控件;
下面主要结合例子详细介绍一下第一种做法,即在原有控件上二次开发,特别是List类型控件中增加其他控件,比如TextBox等。
第二种做法较费功夫,复杂度要高一些,应是第一种方法行不通后再选择。
二.科学原理
其实整个WinForm程序的开发,无外乎控件的显示和控制,具体来说就是先追加到Form里去(this.Controls.Add(new 控件);),然后设置其显示属性,主要是Location和Size,在就是告诉显示时机(什么时候显示,比如一开始隐藏),以及进行事件的绑定,再接着 是显示前给控件加载数据(有些控件的价值可能不在这个,但大多数控件不处理数据是没有应用价值的),然后就是Show。
继承标准控件进行二次开发的过程跟这个类似,下面以ListView为例(给ListView中增加一个TextBox,当点击某Cell区域时显示该部 分内容,编辑后反应到ListView中去)来做说明。
三.实现步骤
1.继承标准控件,增加TextBox,比如
- public partial class ListViewEx : System.Windows.Forms.ListView
- {
- TextBox editText = null;
- public ListViewEx()
- {
- InitializeComponent();
- editText = new TextBox();
- editText.Visible = false;
- editText.Visible = false;
- this.Controls.Add(editText);
- }
- }
2.显示属性的设置
主要是设置textBox的显示大小和显示位置,这个大多是在触发显示发生的事件里设定,一般是MouseUp事件。具体到ListView控件的话,有 一个问题比较难——确定当前Cell的Bound,这得借助API来实现(可能有其他更好的办法,不过我是没找到)。
四. 细节完善
这块主要是根据实际需求一些特别的操作,比如 屏蔽右键,禁止粘贴啥的,也是最费功 夫的地方,可能重写窗口处理函数WndProc,键盘处理函数 ProcessCmdKey等,甚至Windows API,Hook技术等等。估计除了业务逻辑处理,大多就是做这些“细枝末节”的事了,有些可能还是解决不了,至少解决起来很费劲,比如ListView 的GridLine在XP(SP2)环境下,当单击ScrollBar的上下按钮式,可能出现错位的现象,这是个MS的Bug。
五. 需要注意的地方
为了性能起见,资源处理函数最好增加处理,即在Dispose函数中增减关于TextBox的处理,主要是卸载事件和清理对象,防止内存泄露等情况出现。
六.其他说明
具体的例子网上很多(eg1 ), 在此就不贴自己的了。
七.扩展阅读
1.各种自定义控件 (http://msdn.microsoft.com/zh-cn/office/ms171725%28VS.80%29.aspx)