[WPF Bug清单]之(7)——顽固的Error Template
关于WPF数据绑定的Validation更多细节,请参考Data Validation in 3.5。
关于WPF数据绑定的Validation中的ErrorTemplate怎么用,请参考ErrorTemplate Attached Property。
ErrorTemplate将被绘制在Adorner Layer上,关于Adorner Layer,请参考Adorners Overview。
在Adorners Overview里,对Adorner是这样解释的,
Adorners are rendered in an AdornerLayer, which is a rendering surface that is always on top of the adorned element or a collection of adorned elements.
Adorned element的红色是我加的。表面上看,这个adorned element就是一个element,但是这个element的范围有多大呢?对我们的程序会有什么影响呢?看文档很难想到。用过之后才知道,影响太大了。
还有这样一个不太起眼的Note。
Anything placed in the adorner layer is rendered on top of the rest of any styles you have set. In other words, adorners are always visually on top and cannot be overridden using z-order.
这句话是对的。大意就是说这个Adorner layer里的东西,总会被绘制在它所adorn的东西之上。这个无可厚非,人家这样设计,我们就这么用就是了。但是,问题就在于,一个Window里的东西,是可以有层次的,有区域,有可见性的。但是adorner layer不分青红皂白地总在最上。结果就出了问题。请看下面的例子。
这个窗口,就出了两个问题。看图。
启动时如下图所示。
图1. Startup Window
窗体的上下由一个GridSplitter分割,可以上下拖动。
在TextBox中输入一个字符。会产生一个Validation Error,并用默认的ErrorTemplate显示出来。如图2所示。
图2. TextBox in Error
好了,我们慢慢地将GridSplitter向上拖。慢慢地,看到什么了?TextBox消失了,可是那个红框却赖着不走了!如图3所示。
图3. Move GridSplitter Up
再来看看下面的红框。把GridSplitter慢慢地向下拖。TabPanel的空间小了,TextBox也变矮,最后消失,那个红框也很尽忠,化成了一条线也要告诉我们那个TextBox其实还在。如图4所示。
图4. Move GridSplitter Down
再细看看,那个红线甚至已经在TabControl之外了!
当然,我们总可以想办法解决或是绕过这个问题,然后说这不是个问题。但是最自然的代码写出来的东西却不对,就象之前一篇介绍的如何用代码选中一个ListBoxItem一样,很不爽。因为按理说,adorned element都消失了,这个红框也应该跟着消失的。
同系列的其它文章:
[WPF Bug清单](序)与之(1)——可以多选的单选ListBox
[WPF Bug清单]之(2)——RadioButton的IsChecked绑定失效
[WPF Bug清单]之(3)——暗中创建文件的打开文件对话框
[WPF Bug清单]之(4)——点击RadioButton的空白没有反应
[WPF Bug清单]之(5)——隐藏模态对话框后变成非模态
[WPF Bug清单]之(6)——Button的IsCancel属性失效