2017-09-25 64 views
1

我有DataGrid,在每個DataGridRow我有行詳細信息,其中包含幾個控件。如何停止DataGridRow選擇如果在RowDetails中點擊鼠標

我想要什麼,如果有的話則點擊該行的細節裏面:
- 不選擇該行,或者更準確地說,
- 更改現有DataGrid選擇。

我正在考慮處理PreviewMouseDown和MouseDown事件的行爲,不知怎的,使DataGrid跳過選擇過程,但不知道如何繼續。

最後,我將在具有更多信息的細節中使用TabControl,因此我也不希望TabItem單擊來更改DataGrid的現有選擇。

會不會有一種方法來啓動PreviewMouseDown的隧道在電網「DetailsContainer」級別和網格「DetailsContainer」停止的MouseDown的冒泡水平

<DataGrid Name="dgAudit" 
      CanUserReorderColumns="False" 
      CanUserAddRows="False" 
      CanUserDeleteRows="False" 
      CanUserResizeColumns="False" 
      CanUserResizeRows="False" 
      CanUserSortColumns="False" 
      IsReadOnly="True" 
      ItemsSource="{Binding GEOM_ASSET_OC_LIST}" 
      VirtualizingPanel.ScrollUnit="Pixel" 
      RowDetailsVisibilityMode="Visible" 
      > 
    <i:Interaction.Behaviors> 
     <behaviors:DataGridBehaviors /> 
    </i:Interaction.Behaviors> 

    <DataGrid.Columns> 
     <DataGridTextColumn Header="Asset ID" Binding="{Binding ASSET_ID}" Width="200" /> 
     <DataGridTextColumn Header="Asset Type" Binding="{Binding ASSET_TYPE}" Width="200" /> 
     <DataGridTextColumn Header="Last Update By" Binding="{Binding LAST_UPDATE_BY}" Width="150" /> 
     <DataGridTextColumn Header="Last Update Date" Binding="{Binding LAST_UPDATE_DATETIME, StringFormat=\{0:dd.MM.yy HH:mm:ss tt\}}" Width="150" /> 
    </DataGrid.Columns> 
    <DataGrid.RowDetailsTemplate> 
     <DataTemplate> 
      <Grid Name="DetailsContainer"> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="*" /> 
        <ColumnDefinition Width="Auto" /> 
       </Grid.ColumnDefinitions> 
       <TextBlock Name Text="{Binding Notes}" Width="400" HorizontalAlignment="Left" TextWrapping="Wrap"/> 
       <Button Content="Button" Grid.Column="1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/> 
      </Grid> 
     </DataTemplate> 
    </DataGrid.RowDetailsTemplate> 
</DataGrid> 

只是一個快速模擬出一個空的行爲

public class DataGridBehaviors : Behavior<DataGrid> 
{ 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     this.AssociatedObject.MouseDown += DataGrid_MouseDown; 
     this.AssociatedObject.PreviewMouseDown += DataGrid_PreviewMouseDown; 
    } 

    protected override void OnDetaching() 
    { 
     this.AssociatedObject.PreviewMouseDown -= DataGrid_PreviewMouseDown; 
     this.AssociatedObject.MouseDown -= DataGrid_MouseDown; 
     base.OnDetaching(); 
    } 

    private void DataGrid_MouseDown(object sender, MouseButtonEventArgs e) 
    { 
    } 

    private void DataGrid_PreviewMouseDown(object sender, MouseButtonEventArgs e) 
    { 
     DependencyObject obj = (DependencyObject)e.OriginalSource; 
     DataGridDetailsPresenter RowsDetails = FindParent<DataGridDetailsPresenter>(obj); 
     if (RowsDetails != null) 
     { 
      //Skip over selection, maybe temporarily removed native selection handler??? 
     } 
    } 

    public static T FindParent<T>(DependencyObject child) where T : DependencyObject 
    { 
     //get parent item 
     DependencyObject parentObject = VisualTreeHelper.GetParent(child); 

     //we've reached the end of the tree 
     if (parentObject == null) return null; 

     //check if the parent matches the type we're looking for 
     T parent = parentObject as T; 
     if (parent != null) 
      return parent; 
     else 
      return FindParent<T>(parentObject); 
    } 

    private static T GetVisualChild<T>(DependencyObject parent) where T : Visual 
    { 
     T child = default(T); 

     int numVisuals = VisualTreeHelper.GetChildrenCount(parent); 
     for (int i = 0; i < numVisuals; i++) 
     { 
      Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); 
      child = v as T; 
      if (child == null) 
      { 
       child = GetVisualChild<T>(v); 
      } 
      if (child != null) 
      { 
       break; 
      } 
     } 
     return child; 
    } 
} 
+0

可能包括寫只讀屬性設置爲「真」 –

回答

0

我發現了另一種可能的解決方法。通過在DataGridRowHeader內部創建一個小的Canvas,然後在下一個子容器設置ClipsToBoundsfalse。然後,它不包含標題,但也可以在不影響DataGrid的當前選擇的情況下點擊。這是綁定到行細節的IsExpanded,看起來是部分。

警告一句話是,如果行詳細信息包含大量數據,並且代碼如下所示,可能效率非常低,加載時間和滾動延遲。取決於是否使用virtualization。這些數據將與該行同時加載,並且可能效率很低,因爲這些控件在RowDetailsTemplate中時會按需加載。可能最好是嚴格控制通過User Control或動態加載此數據。

另外,您可能需要聽取DataGridLayoutUpdated事件以調整詳細控件的寬度。

<DataGrid.RowHeaderTemplate> 
    <DataTemplate> 
     <Grid> 
      <Expander Template="{StaticResource StretchyExpanderTemp}" 
         OverridesDefaultStyle="True" 
         Header="" 
         HorizontalAlignment="Right" 
         VerticalAlignment="Top" 
         Expanded="Expander_Expanded" Collapsed="Expander_Collapsed" 
         IsExpanded="{Binding DataContext.IsExpanded, RelativeSource={RelativeSource AncestorType=DataGridRowHeader}}" /> 

      <Canvas Background="BlueViolet" 
        Width="5" 
        VerticalAlignment="Top" 
        HorizontalAlignment="Left" 
        Height="5"> 
       <TabControl Name="tcAA" 
          TabStripPlacement="Left" 
          Margin="20,18,0,0" 
          Height="185" 
          Width="500" 
          VerticalAlignment="Top" 
          HorizontalAlignment="Left" 
          ItemsSource="{Binding DataContext.AAUDIT, RelativeSource={RelativeSource AncestorType=DataGridRowHeader}}" 
          SelectedIndex="0" 
          ClipToBounds="False" 
          Visibility="{Binding DataContext.IsExpanded, RelativeSource={RelativeSource AncestorType=DataGridRowHeader}, Converter={StaticResource bool2VisibilityConverter}}" 
          > 
        ... 
        <TabControl.ItemTemplate> 
         <DataTemplate> 
          <Grid> 
           <TextBlock Text="{Binding DISPLAY_NAME}" /> 
          </Grid> 
         </DataTemplate> 
        </TabControl.ItemTemplate> 
        <TabControl.ContentTemplate> 
         <DataTemplate> 
          ... 
         </DataTemplate> 
        </TabControl.ContentTemplate> 
       </TabControl> 
      </Canvas> 
     </Grid> 
    </DataTemplate> 
</DataGrid.RowHeaderTemplate> 

<DataGrid.RowDetailsTemplate> 
    <DataTemplate> 
     <Grid Height="185" > 
     </Grid> 
    </DataTemplate> 
</DataGrid.RowDetailsTemplate> 

因爲它站在這裏是什麼我生產一個簡單的例子: enter image description here

1

不幸的是,目前的WPF DataGrid的實現,這是不可能實現你想要什麼。

DataGridDetailsPresenter寄存器使用EventManager API的MouseLeftButtonDownEvent路由事件class event handler

EventManager.RegisterClassHandler(
    typeof(DataGridDetailsPresenter), 
    MouseLeftButtonDownEvent, 
    new MouseButtonEventHandler(OnAnyMouseLeftButtonDownThunk), 
    true); 

注意,它被設置爲true最後一個參數。這是一個標誌,指示聽衆是否想要了解已處理的事件。在這種情況下,即使您在任何級別將RoutedEventArgs.Handled屬性設置爲true,仍然會調用內部DataGridDetailsPresenter的事件處理程序。

此事件處理程序負責將DataRow聚焦在單擊詳細信息視圖中。你一定知道,在WPF中,類事件處理程序在實例事件處理程序之前被調用。因此,左側點擊一個詳細信息行的演示者會發生的第一件事是包含行(實際上,該行的第一個單元格)的焦點。

請注意,此行爲也管理RowPresenter中虛擬項目的實現,因此禁用它可能會導致不需要的GUI副作用。

您可以將您的容器GridIsHitTestVisible屬性設置爲false,這將禁用自動行選擇行爲。但顯然,您無法處理行內細節內的任何點擊。

+0

大答案,可怕的事實,所以我可以留下檢查如果點擊來自行的細節,如果是的話,保存現有的選定項目/索引,一旦控件已經完成了它們的自然行爲重新應用選擇......或者那裏 – Hank

相關問題