由于项目功能的需要,要做一个运行时的设计器,首先想到的做法就是模仿VS2005的IDE设计器,有设计窗口,有属性格等。刚开始由于没有时间深入探讨,通过监听Windows消息的方法做了一个,效果不是怎么的好,后来经不断的查资料,发现Framework已经提供了很好的类给我们调用VS IDE的设计器,设计终于走上正道,于是重写了原来的代码,实现了运行时设计的功能。
我们开发使用到VS的属性格,其处理错误的方式对开发人员来说没有什么,但是如果我们把这种提示的方式交给客户使用,客户肯定是不满意的,因此,我们还必须处理错误提示的形式。对于有些设计时的控件,其属性或是唯一或是不断递增的,我们也必须要处理,不能给客户每拖动一个控件,要做一大堆的设置,只显示客户需要的属性,提供复制、撤消和恢复功能等。我们的设计器必须有一些智能化的功能在里面,用户使用起来才觉得方便。
在该设计器中首先使用到的控件是属性格控件(PropertyGrid),此处使用了一个开源的属性格扩展控件(PropertyGridEx)该控件对自定义属性有很好的处理,这正是我需要的,该控件通过自定义属性实现了一个消息的提示,相对Framework中的PropertyGrid有了更好的展现,但还不能符合我的要求,还有,对属性更改的验证比较麻烦,不灵活,于是本人对原码进行了小的修改,增加了属性更改前的验证事件,允许开发人员对用户输入的数据时行验证,由开发人员在些处向用户作更好的提示,并取消不成功的修改。该修改可能使得控件的整体性差了点,但对开发人员来说更灵活了,可以实现很复杂的功能。该控件就不提供原码了,需要的可以到http://www.codeproject.com/去搜索一下,对于更改前的验证事件,大家可以去研究研究。在此处说说该控件的插曲:该控件(属性格)中修改了某个值,代码中是通过Microsoft.VisualBasic命名空间内的Interaction类实现,我相信该类和C#中的Type的反射差不多,于是在完成了整个IDE的设计后才发现,用鼠标或键盘移动控件,属性格的值可以改变,但是在属性格改变控件的位置后,控件是可以正常的起到设定的位置,但IDE的选中控件的窗口(Hook窗口)并没有跟着移动,改变大小也是一样。很长时间都找不到原因所在,后来无意在DesignSurface的代码中发现使用的是TypeDescriptor进行赋值,于是把原认为没有问题的PropertyGridEx的代码更改,问题解决,我猜想,可以TypeDescriptor更改值的时候,可能内部会有一个消息通知机制,而一般的反射没有,而DesignSurface是通过在内部监听属性更改的消息而有所动作(没有反射Framework的程序集研究)。
效果图如下:
待续...