2008-09-30 43 views
41

看一看這個非常簡單的例子WPF程序:WPF中的GroupBox標題是否會吞下鼠標點擊?

<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 

    <GroupBox> 
     <GroupBox.Header> 
      <CheckBox Content="Click Here"/> 
     </GroupBox.Header> 
    </GroupBox> 
</Window> 

所以我有一個分組框,其標題是一個複選框。我們都做了這樣的事情 - 通常您將GroupBox的內容綁定到CheckBox未被選中時禁用的方式。

但是,當我運行此應用程序並單擊CheckBox時,我發現有時候我的鼠標點擊被吞下,CheckBox的狀態不會改變。如果我是對的,那就是當我點擊GroupBox頂部邊框所在的確切像素行時。

有人可以複製此?爲什麼會發生這種情況,是否有解決辦法?

編輯:將GroupBox的BorderThickness設置爲0解決了這個問題,但顯然它刪除了邊框,所以它看起來不再像組合框了。

+4

完整的模板讓我們投票修復了此漏洞:HTTPS ://connect.microsoft.com/VisualStudio/feedback/details/539427/any-control-placed-in-groupboxs-header-will-be-not-complete-accessable-click-hover-etc – codekaizen 2010-09-16 17:00:32

+0

非常感謝您的支持張貼這個!現在我知道這是一個錯誤。 – 2012-01-30 09:53:28

+2

在.NET 4.5中修復。你可以安裝.NET 4.5來修復你的4.0應用程序。 – 2012-10-03 21:02:32

回答

18

它似乎是GroupBox的控件模板中的一個微妙的錯誤。我通過編輯GroupBox的默認模板並將名爲'Header'的邊框移動到控件模板Grid元素中的最後一項來找到問題,問題自行解決。

原因在於帶有TemplateBinding BorderBrush的其他Border元素之一在可視化樹中進一步向下並捕獲鼠標單擊,這就是爲什麼將BorderBrush設置爲null允許CheckBox正確接收鼠標單擊。

以下是GroupBox的結果樣式。它與控件的默認模板幾乎相同,除了名爲「Header」的Border元素(現在是Grid的最後一個子元素),而不是第二個。

<BorderGapMaskConverter x:Key="BorderGapMaskConverter"/> 

<Style x:Key="GroupBoxStyle1" 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.RowDefinitions> 
         <RowDefinition Height="Auto"/> 
         <RowDefinition Height="Auto"/> 
         <RowDefinition Height="*"/> 
         <RowDefinition Height="6"/> 
        </Grid.RowDefinitions> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="6"/> 
         <ColumnDefinition Width="Auto"/> 
         <ColumnDefinition Width="*"/> 
         <ColumnDefinition Width="6"/> 
        </Grid.ColumnDefinitions> 
        <Border Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="1" Grid.RowSpan="3" Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4"/> 
        <ContentPresenter Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="2"/> 
        <Border Grid.ColumnSpan="4" Grid.Row="1" Grid.RowSpan="3" BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4"> 
         <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> 
        <Border x:Name="Header" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Padding="3,1,3,0"> 
         <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header" RecognizesAccessKey="True"/> 
        </Border> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
4

如果更改GroupBox的BorderBrush,它可以工作!

<GroupBox BorderBrush="{x:Null}"> 

我知道這打敗了目標,但它確實證明問題出在哪裏!

+0

無論如何,這可能會有所幫助。我們可能能夠在GroupBox後面放置一個「真實」的邊框來僞造它。我會拭目以待,看看我們能否得到更多答覆,但這可能與我接受的答案接近。 – 2008-09-30 07:35:09

11

的替代解決方案我提出在派生分組框中正在實施OnApplyTemplate:

public override void OnApplyTemplate() 
{ 
    base.OnApplyTemplate(); 
    if (Children.Count == 0) return; 

    var grid = GetVisualChild(0) as Grid; 
    if (grid != null && grid.Children.Count > 3) 
    { 
    var bd = grid.Children[3] as Border; 
    if (bd != null) 
    { 
     bd.IsHitTestVisible = false; 
    } 
    } 
} 
23

伊恩奧克斯答案充塞向上的標籤順序,使得所述頭而來的內容之後。可以修改控件模板,使邊框無法獲得焦點。

要做到這一點,修改模板,以便在第二和第三邊界(無論是在網格行1)具有IsHitTestVisible=false

下面

<BorderGapMaskConverter x:Key="GroupBoxBorderGapMaskConverter" /> 

<Style x:Key="{x:Type GroupBox}" TargetType="{x:Type GroupBox}"> 
    <Setter Property="Control.BorderBrush" Value="#FFD5DFE5" /> 
    <Setter Property="Control.BorderThickness" Value="1" /> 
    <Setter Property="Control.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 Name="Header" Padding="3,1,3,0" Grid.Row="0" Grid.RowSpan="2" Grid.Column="1"> 
         <ContentPresenter ContentSource="Header" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" /> 
        </Border> 
        <Border CornerRadius="4" Grid.Row="1" Grid.RowSpan="3" Grid.Column="0" Grid.ColumnSpan="4" BorderThickness="{TemplateBinding Control.BorderThickness}" BorderBrush="#00FFFFFF" Background="{TemplateBinding Control.Background}" IsHitTestVisible="False" /> 
        <ContentPresenter Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Margin="{TemplateBinding Control.Padding}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"/> 
        <Border CornerRadius="4" Grid.Row="1" Grid.RowSpan="3" Grid.ColumnSpan="4" BorderThickness="{TemplateBinding Control.BorderThickness}" BorderBrush="#FFFFFFFF" IsHitTestVisible="False"> 
         <UIElement.OpacityMask> 
          <MultiBinding Converter="{StaticResource GroupBoxBorderGapMaskConverter}" ConverterParameter="7"> 
           <Binding ElementName="Header" Path="ActualWidth" /> 
           <Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}" /> 
           <Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}" /> 
          </MultiBinding> 
         </UIElement.OpacityMask> 
         <Border BorderThickness="{TemplateBinding Control.BorderThickness}" BorderBrush="{TemplateBinding Control.BorderBrush}" CornerRadius="3"> 
          <Border BorderThickness="{TemplateBinding Control.BorderThickness}" BorderBrush="#FFFFFFFF" CornerRadius="2" /> 
         </Border> 
        </Border>       
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style>