2013-04-25 180 views
2

我在WPF頁面上有一個DataGrid,並希望阻止用戶選擇單元格。由於此功能僅用於測試,因此我不想在代碼中更改所有內容。停止用戶選擇/取消選擇WPF DataGrid中的行

我的DataGrid已填滿之後,我確保選中了它的所有行。現在我想確保用戶不能選擇/取消選擇行。

我試着設置IsEnabled = falseIsHitTestVisible = "False"但這兩個解決方案都禁用滾動條。

有沒有辦法做到這一點?

+0

只要爲DataGridRow或DataGridCell對象設置IsHitTestVisible = False呢?您可以在'' – Rachel 2013-04-25 15:32:07

+0

@Rachel:任何代碼示例中使用隱式樣式輕鬆實現該功能。 – mans 2013-04-25 16:06:03

+0

當然,我添加了下面的代碼示例以及一些解釋 – Rachel 2013-04-25 16:19:07

回答

9

爲什麼不只是爲您的DataGridRowDataGridCell對象設置IsHitTestVisible="False"

這很容易在<DataGrid.Resources>使用隱式樣式做的,應僅在行或單元格禁用命中測試,這應該離開的其他領域DataGrid功能,如標題或滾動條

<DataGrid.Resources> 
    <Style TargetType="{x:Type DataGridRow}"> 
     <Setter Property="IsHitTestVisible" Value="False" /> 
    </Style> 
</DataGrid.Resources> 
+0

tabulator仍然讓你選擇行 – blindmeis 2015-11-23 14:14:55

+0

@blindmeis啊,你可能必須將'KeyboardNavigation.IsTabStop'設置爲False,然後 – Rachel 2015-11-23 15:09:49

+0

我需要別的東西?我沒有在我的項目中工作 – blindmeis 2015-11-24 08:08:14

0

你有兩個選擇:

  1. 您禁用風格選擇(在這種情況下,你只關閉在款式顏色,但身體的SelectedItem或SelectedItems會發生變化)。您可以輕鬆瞭解如何關閉選擇樣式。

  2. 您可以禁用更改選擇而不更改SelectedItem或SelectedItems(在這種情況下,您的選擇樣式也不會更改)。

在WPF我不喜歡重寫標準控件。所以,我們需要一個Behavior

public class DisableSelectionDataGridBehavior : Behavior<DataGrid> 
{ 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObjectOnPreviewMouseLeftButtonDown; 
    } 

    private void AssociatedObjectOnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     var dependencyObject = AssociatedObject.InputHitTest(e.GetPosition(AssociatedObject)) as DependencyObject; 
     if (dependencyObject == null) return; 

     var elements = dependencyObject.GetParents().OfType<FrameworkElement>().Where(DataGridCellExtended.GetIsDisableSelection).ToList(); 
     if (!elements.Any()) return; 

     e.Handled = true; 

     var args = new MouseButtonEventArgs(e.MouseDevice, e.Timestamp, e.ChangedButton, e.StylusDevice); 
     args.RoutedEvent = UIElement.MouseLeftButtonDownEvent; 
     args.Source = e.Source; 

     elements.ForEach(item => 
     { 
      item.RaiseEvent(args); 
      var children = item.GetChildren<FrameworkElement>(); 
      children.ForEach(child => child.RaiseEvent(args)); 
     }); 
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 
     AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObjectOnPreviewMouseLeftButtonDown; 
    } 
} 

其次,你需要一個Extended類:

public class DataGridCellExtended 
{ 
    public static readonly DependencyProperty IsDisableSelectionProperty = DependencyProperty.RegisterAttached("IsDisableSelection", typeof(Boolean), typeof(DataGridCellExtended)); 

    public static Boolean GetIsDisableSelection(DependencyObject o) 
    { 
     return (Boolean)o.GetValue(IsDisableSelectionProperty); 
    } 

    public static void SetIsDisableSelection(DependencyObject o, Boolean value) 
    { 
     o.SetValue(IsDisableSelectionProperty, value); 
    } 
} 

最後在XAML你需要的東西是這樣的:

<DataGridTemplateColumn.CellTemplate> 
    <DataTemplate DataType="{x:Type items:YourViewModel}"> 
     <StackPanel Orientation="Horizontal" 
        HorizontalAlignment="Center" 
        VerticalAlignment="Center"> 
      <Button Margin="0" 
        extends:DataGridCellExtended.IsDisableSelection="True"> 

       <Path Data="M5,0L3,2 1,0 0,1 2,3 0,5 1,6 3,4 5,6 6,5 4,3 6,1z" 
         Fill="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGridCell}}" 
         Width="12" 
         Height="12" 
         Stretch="Uniform"/> 
      </Button> 
     </StackPanel> 
    </DataTemplate> 
</DataGridTemplateColumn.CellTemplate> 

你可以寫你的擴展類的邏輯。

public static IEnumerable<DependencyObject> GetParents(this DependencyObject element) 
{ 
    if (element != null) 
    { 
     while (true) 
     { 
      var parent = element.GetParent(); 
      var dependencyObject = parent; 
      element = parent; 
      if (dependencyObject == null) 
      { 
       break; 
      } 
      yield return element; 
     } 
     yield break; 
    } 
    else 
    { 
     throw new ArgumentNullException("element"); 
    } 
} 

private static IEnumerable<DependencyObject> GetChildrenRecursive(this DependencyObject element) 
{ 
    if (element != null) 
    { 
     for (var i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) 
     { 
      var dependencyObject = VisualTreeHelper.GetChild(element, i); 
      yield return dependencyObject; 
      foreach (var childrenRecursive in dependencyObject.GetChildrenRecursive()) 
      { 
       yield return childrenRecursive; 
      } 
     } 
    } 
    else 
    { 
     throw new ArgumentNullException("element"); 
    } 
}