Post by "gw0506", 08-04-2008, 18:31
-----------------------------------------------------
众所周知WinForm Control都有一个属性叫Name。看起来很简单,就是一个control的名字,代号而已,看起来没什么起眼的。但是,其实它并不是表面看起来那么简单,或者说,比较复杂的。
DesignTime下,选中MS Button,PropertyGrid上会显示一个属性(name)。它生成的code是this.button1.Name = "button1"。问题来了,为什么它生成的code不是this.button1.(name) = "button1"呢?
经查发现给属性加一个Attribute就能使它显示的时候加个括号,它叫 ParenthesizePropertyName。
可是翻开Reflector一看,不对啊!!Control.Name上没有这个Attribute呀,而且它的Browsable是false!这就怪了,(name)和Name肯定不是一个东西!
好吧,找找Designer看看。果然有所发现。ControlDesigner中有一个ShadowProperty叫Name,那看来可能是这个吧。可是这个Name没有加任何Attribute。那肯定也不对!
又找了Component,ComponentDesigner,IComponent等等,压根没发现Name的影子!!
(一年后......)
终于找到了!
原来有个叫ComponentDocumentDesigner的东西,它里面抓了个DesignerExtenders,而DesignerExtenders里有个NameExtenderProvider,它会给Component添一个Name属性,而这个属性的Attribute终于符合PropertyGrid上(name)的表现了。[Category("Design"), ParenthesizePropertyName(true), SRDescription("DesignerPropName"), MergableProperty(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 。这时发现,这个name只是显示,不生成code!
有点晕,理一理。NameExtenderProvider提供了一个(name)让大家看。但是他不生成code。由于它操纵的是 component.Site.Name,它与ControlDesigner下的ShadowProperty,也就是designer中的Name,属性用的是同一份实例。ShadowProperty可以生成code。于是用户改变(name)属性,是可以生成code的。当运行起来之后,ShadowProperty就被摘了,而Control.Name这个Browsable是false的东西就会按照生成的code,乖乖的被赋值了!!!
至此,一个简单的string类型的Name属性就被设置完成了~ 很无聊吧!无聊么?
ComponentDocumentDesigner是指Component本身根文档设计器。上面提到的this.button1.Name = "button1"中的第一个button1就是ComponentDocumentDesigner搞的,所以它是很必要的。但是Control上又有一个Name属性,总不能把它也放到PropertyGrid上吧,那样会出现两个属性都是Name。所以要把Control.Name封掉,让它 Browsable等于false。但是这样就不能对它进行设置,也就不可能生成code。为了解决这个问题,只好借助ShadowProperty了。 ShadowProperty封装了和NameExtenderPovider中Name一样的实例。所以当用户改(name)的时候,ControlDesigner的ShouldSerializeName()就会返回true,于是code就生成了。
这个过程就像接力一样完成了。累死了~~~~~~
|