WPF 控件开发之 IAddChild
最近在写一个控件的ProtoType时遇到一个问题: IAddChild到底有什么用?
在上网搜了一圈,没发现太多的专门说明。没办法,只能自己干了
打开vs2008,reflactor ,然后开始看痛苦地debug Disassembly,该死的MS,soucecode开放得还不够啊。
一阵乱七八糟之后,再仔细确认了反编译后的代码,结论让我崩溃了,IAddChild没用了!!!
如果你想真的想用的话,请用IList,或IDictionary,或ArrayExtension或ContentPropertyAttribute代替。
IAddChild几乎没什么用了,并且MS很无耻地继承了一下
然后MS自己满世界地判断是不是IAddChildInternal,~!@#$%^&*
接下来分头看看VS2008 IDE, RunTime, 以及Blend如何干活
1. VS2008 IDE (就是所谓的DesignTime)
在微软VS2008 Host.Designer.Load()过程中,找到
|
你会发现IAddChild连个影都没有,只有IAddChildInternal, IList等在工作。:(
随便说说代码里的执行判断顺序:
IDictionary -> IList -> ArayExtension -> IAddChildInternal -> ContentPropertyAttritute.
有兴趣的可以自己去读读代码,这儿就不贴了。
2. RunTime
直接定位到:PresentationFramework.dll!System.Windows.Markup.XamlReader.LoadBaml()
在load baml中
a) 在创建实例之前,XamlReader 会先为该判断该类型并缓存一个标记 (System.Windows.Markup.ReaderFlags)
PresentationFramework.dll!System.Windows.Markup.BamlRecordReader.GetFlagsFromType() |
标记的优先级: IDictionary -> IList -> ArayExtension -> IAddChildInternal
b) 接下来就该创建实例了,XamlReader会根据之前缓存的标记来处理
PresentationFramework.dll!System.Windows.Markup.BamlRecordReader.SetPropertyValueToParent() |
同样的处理顺序: IDictionary -> IList -> ArayExtension -> IAddChildInternal
3. Blend
Blend 的Debug能力还是弱,不像VS IDE还有DisAssembly能玩,只能黑读code,累啊,现在还不敢说完全确定,不过发现它的机制和IDE下完全不一样(DesignTime),
IList, IDictionary接口的隐式实现都无效,估计Blend不是通过接口走的。
Blend暂时没有具体的结论,等我把代码读完了,再补充完整吧。