在WPF BUG清单之二,介绍过RadioButton在绑定上的一个Bug。现在再来介绍它的另一个造成RadioButton的点击事件处理不正确的BUG。现象是:点在RadioButton的范围内,可这个RadioButton就是选不中。
先来看一个例子。Windows里一个常见的对话框,用了多个RadioButton。如下图所示。
图1. RadioButton使用范例
把RadioButton放在GroupBox的Header上,是很常见的一个用例,而且被微软的UX Guide所认可。
大家可以在自己的电脑上点点这些RadioButton,只要点在圆圈或文字范围内,就会被选中。
我们现在用WPF来实现这个效果。实现的方式有很多。
1. 直接在Header里放一个RadioButton。简单,不可复用。
2. 使用HeaderTemplate,里面放个RadioButton。比上面的复杂些,结果一样。
3. 使用ControlTemplate,还是里面放个RadioButton。复用性好些。
简单起见,我们用第一种方式来演示这个Bug。代码如下:附源代码

运行的效果如下图。
图2. RadioButton点击Bug示例
PS:本来想做个XBAP程序放上来让大家直接点点。结果没找着上传.exe的地方。
这个BUG的根源应该是由于颜色造成的。可以发现鼠标在Header RadioButton上移动时,只有鼠标处在有颜色区域的上方时,RadioButton才认为自己是MouseOver。但是特意给RadioButton的Header设置了Background之后,问题依旧。
这个问题让我们的QA和Developer同时抓狂不已。作为高品质的软件,这种看上去的小问题也是不可容忍的。解决方式是有的,但是丑恶得不敢拿出来给大家看。还是等神人出场或是.NET Framework 4.0吧。
-----------------------------------------总结的分割线---------------------------------------
RadioButton目前已有两个BUG入帐,荣登WPF BUG榜第一。但是RadioButton同学也不要高兴得太早,我们的BUG主力ListBox以其义兄ListView还没发威呢。Button同学就放弃吧,作为最简单的控件之一,也得给我们点儿信心啊。
-----------------------------------------更新的分割线----------------------------------------
今天看了winkingzhang的[WPF]RadioButton在Group的Header区部分不响应鼠标选择的bug分析,深受启发。winkingzhang发现了问题的根源并不算是RadioButton,而是GroupBox。在此向各位读者深表歉意。
于是再次试图找到解决方案。Winkingzhang建议我们看VisualTree,个人感觉有个东西更直观一些,就是ControlTemplate,VisualTree的来源就是ControlTemplate。从Blend中找到了GroupBox的默认Style,如下:

通过修改这个Style发现,出问题的就是Template里最下面的那个Border(从实际位置上就是winkingzhang说的最上面)。那么Fix的方式似乎也就出来了,给Header外面的那个Border设置一个ZIndex为1。或是把最下面的Border放上Header的Border的上面(在XAML中的上部)去。都可以“解决”这个问题。
然而修改默认Style去Fix一个Bug其实是非常恶劣的。因为这样控件就会只用这个Style,而不会根据主题自动地切换自己Style以符合用户的主题设置。笔者水平所限,还不能给出这个问题的解决方案。
最后更新于2009年3月19日。
同系列的其它文章:
[WPF Bug清单](序)与之(1)——可以多选的单选ListBox
[WPF Bug清单]之(2)——RadioButton的IsChecked绑定失效
[WPF Bug清单]之(3)——暗中创建文件的打开文件对话框
[WPF Bug清单]之(5)——隐藏模态对话框后变成非模态
[WPF Bug清单]之(6)——Button的IsCancel属性失效
[WPF Bug清单]之(7)——顽固的Error Template