[WPF Bug清单]之(4)——点击RadioButton的空白没有反应

WPF BUG清单之二,介绍过RadioButton在绑定上的一个Bug。现在再来介绍它的另一个造成RadioButton的点击事件处理不正确的BUG。现象是:点在RadioButton的范围内,可这个RadioButton就是选不中。

 

先来看一个例子。Windows里一个常见的对话框,用了多个RadioButton。如下图所示。

 

1. RadioButton使用范例

 

RadioButton放在GroupBoxHeader上,是很常见的一个用例,而且被微软的UX Guide所认可。

 

大家可以在自己的电脑上点点这些RadioButton,只要点在圆圈或文字范围内,就会被选中。

我们现在用WPF来实现这个效果。实现的方式有很多。

1.       直接在Header里放一个RadioButton。简单,不可复用。

2.       使用HeaderTemplate,里面放个RadioButton。比上面的复杂些,结果一样。

3.       使用ControlTemplate,还是里面放个RadioButton。复用性好些。

 

简单起见,我们用第一种方式来演示这个Bug。代码如下:附源代码 

 

 

ContractedBlock.gif ExpandedBlockStart.gif Sample code
    <StackPanel Margin="12">

        
<TextBlock Margin="0,0,0,5" TextWrapping="Wrap">

            
<Run FontWeight="Bold">Bug Description:</Run>

            
<Run></Run>

        
</TextBlock>

        
<GroupBox Padding="9" >

            
<GroupBox.Header>

                
<RadioButton Content="Header RadioButton" GroupName="header"/>

            
</GroupBox.Header>

            
<GroupBox.Content>

                
<StackPanel>

                    
<RadioButton Content="Common RadioButton"/>

                    
<RadioButton Content="Common RadioButton"/>

                
</StackPanel>

            
</GroupBox.Content>

        
</GroupBox>

        
<GroupBox Padding="9" >

            
<GroupBox.Header>

                
<RadioButton Content="Header RadioButton" GroupName="header"/>

            
</GroupBox.Header>

            
<GroupBox.Content>

                
<StackPanel>

                    
<RadioButton Content="Common RadioButton"/>

                    
<RadioButton Content="Common RadioButton"/>

                
</StackPanel>

            
</GroupBox.Content>

        
</GroupBox>

    
</StackPanel>

 

运行的效果如下图。

 

2. RadioButton点击Bug示例

 

PS:本来想做个XBAP程序放上来让大家直接点点。结果没找着上传.exe的地方。

这个BUG的根源应该是由于颜色造成的。可以发现鼠标在Header RadioButton上移动时,只有鼠标处在有颜色区域的上方时,RadioButton才认为自己是MouseOver。但是特意给RadioButtonHeader设置了Background之后,问题依旧。

 

这个问题让我们的QADeveloper同时抓狂不已。作为高品质的软件,这种看上去的小问题也是不可容忍的。解决方式是有的,但是丑恶得不敢拿出来给大家看。还是等神人出场或是.NET Framework 4.0吧。

 

-----------------------------------------总结的分割线---------------------------------------

 

RadioButton目前已有两个BUG入帐,荣登WPF BUG榜第一。但是RadioButton同学也不要高兴得太早,我们的BUG主力ListBox以其义兄ListView还没发威呢。Button同学就放弃吧,作为最简单的控件之一,也得给我们点儿信心啊。

-----------------------------------------更新的分割线----------------------------------------

今天看了winkingzhang[WPF]RadioButton在GroupHeader区部分不响应鼠标选择的bug分析,深受启发。winkingzhang发现了问题的根源并不算是RadioButton,而是GroupBox。在此向各位读者深表歉意。

于是再次试图找到解决方案。Winkingzhang建议我们看VisualTree,个人感觉有个东西更直观一些,就是ControlTemplateVisualTree的来源就是ControlTemplate。从Blend中找到了GroupBox的默认Style,如下:

 

ContractedBlock.gif ExpandedBlockStart.gif GroupBox Default Style
<Style TargetType="{x:Type GroupBox}">
    
<Setter Property="BorderBrush" Value="#D5DFE5"/>
    
<Setter Property="BorderThickness" Value="1"/>
    
<Setter Property="Template">
        
<Setter.Value>
            
<ControlTemplate TargetType="{x:Type GroupBox}">
                
<Grid SnapsToDevicePixels="true">
                    
<Grid.ColumnDefinitions>
                        
<ColumnDefinition Width="6"/>
                        
<ColumnDefinition Width="Auto"/>
                        
<ColumnDefinition Width="*"/>
                        
<ColumnDefinition Width="6"/>
                    
</Grid.ColumnDefinitions>
                    
<Grid.RowDefinitions>
                        
<RowDefinition Height="Auto"/>
                        
<RowDefinition Height="Auto"/>
                        
<RowDefinition Height="*"/>
                        
<RowDefinition Height="6"/>
                    
</Grid.RowDefinitions>
                    
<Border Background="{TemplateBinding Background}"
                            BorderBrush
="Transparent"
                            BorderThickness
="{TemplateBinding BorderThickness}"
                            CornerRadius
="4" Grid.Column="0" Grid.ColumnSpan="4"
                            Grid.Row
="1" Grid.RowSpan="3" Visibility="Collapsed"/>
                    
<Border x:Name="Header" Padding="3,1,3,0" Grid.Column="1"
                            Grid.Row
="0" Grid.RowSpan="2">
                        
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                          ContentSource
="Header" RecognizesAccessKey="True"/>
                    
</Border>
                    
<ContentPresenter Margin="{TemplateBinding Padding}"
                                      SnapsToDevicePixels
="{TemplateBinding SnapsToDevicePixels}"
                                      Grid.Column
="1" Grid.ColumnSpan="2" Grid.Row="2"/>
                    
<Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}"
                            CornerRadius
="4" Grid.ColumnSpan="4" Grid.Row="1" Grid.RowSpan="3">
                        
<Border.OpacityMask>
                            
<MultiBinding Converter="{StaticResource BorderGapMaskConverter}" ConverterParameter="7">
                                
<Binding Path="ActualWidth" ElementName="Header"/>
                                
<Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
                                
<Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
                            
</MultiBinding>
                        
</Border.OpacityMask>
                        
<Border BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness
="{TemplateBinding BorderThickness}"
                                CornerRadius
="3">
                            
<Border BorderBrush="White"
                                    BorderThickness
="{TemplateBinding BorderThickness}"
                                    CornerRadius
="2"/>
                        
</Border>
                    
</Border>
                
</Grid>
            
</ControlTemplate>
        
</Setter.Value>
    
</Setter>
</Style>

 

通过修改这个Style发现,出问题的就是Template里最下面的那个Border(从实际位置上就是winkingzhang说的最上面)。那么Fix的方式似乎也就出来了,给Header外面的那个Border设置一个ZIndex1。或是把最下面的Border放上HeaderBorder的上面(在XAML中的上部)去。都可以“解决”这个问题。

 

然而修改默认StyleFix一个Bug其实是非常恶劣的。因为这样控件就会只用这个Style,而不会根据主题自动地切换自己Style以符合用户的主题设置。笔者水平所限,还不能给出这个问题的解决方案。

最后更新于2009年3月19日。

 

 

同系列的其它文章:

[WPF Bug清单]()与之(1)——可以多选的单选ListBox

[WPF Bug清单](2)——RadioButtonIsChecked绑定失效

[WPF Bug清单](3)——暗中创建文件的打开文件对话框

[WPF Bug清单](5)——隐藏模态对话框后变成非模态

[WPF Bug清单](6)——ButtonIsCancel属性失效

[WPF Bug清单](7)——顽固的Error Template

[WPF Bug清单](8)——RowDefinitionMaxHeight在一定条件下失效

[WPF Bug清单](9)——消失的光标

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值