2016-07-05 65 views
0

你好,这一切听起来微不足道,但我想停止拖累WPFDataGrid如何停止拖动选择的WPF数据网格

我有一个简单的网格状

​​

我怎么可以停止选择单击拖动时可进行多项选择,并可通过Shift和Ctrl进行多项选择。

感谢

回答

0

尝试破解:创建一个继承DataGrid一个类并重写​​,而无需调用base.OnMouseMove

+0

它杀死拖放行为,然后 – Muds

+0

所以添加如果并检查是否是拖放 – Mikolaytis

+0

和更多的污垢..... – Muds

0

DataGrid控制不适合自定义选择手势,反正一些黑客可以执行,以达到您目标。所有的 首先,我们需要一个辅助类:

public static class ReflectionHelper 
{ 
    public static T GetPropertyValue<T>(object owner, string propertyName) where T : class 
    { 
     Type ownerType = owner.GetType(); 
     PropertyInfo propertyInfo = ownerType.GetProperty(propertyName, 
      BindingFlags.Instance | BindingFlags.NonPublic); 

     while (propertyInfo == null) 
     { 
      ownerType = ownerType.BaseType; 
      propertyInfo = ownerType.GetProperty(propertyName, 
       BindingFlags.Instance | BindingFlags.NonPublic); 
     } 

     return propertyInfo.GetValue(owner, null) as T; 
    } 

    public static void Execute(object owner, string methodName, params object[] parameters) 
    { 
     Type ownerType = owner.GetType(); 
     MethodInfo methodInfo = ownerType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic); 

     while (methodInfo == null) 
     { 
      ownerType = ownerType.BaseType; 
      methodInfo = ownerType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic); 
     } 
     methodInfo.Invoke(owner, parameters); 
    } 
} 

我不喜欢它,但需要反思。首先,我们需要建立我们自己的中为了DataGridRowHeader改变其OnClick代码:

public class DataGridRowHeader : System.Windows.Controls.Primitives.DataGridRowHeader 
{ 
    protected override void OnClick() 
    { 
     if (Mouse.Captured == this) 
     { 
      base.ReleaseMouseCapture(); 
     } 
     DataGrid dataGridOwner = ReflectionHelper.GetPropertyValue<DataGrid>(this, "DataGridOwner"); 
     DataGridRow parentRow = ReflectionHelper.GetPropertyValue<DataGridRow>(this, "ParentRow"); 

     if (dataGridOwner != null && parentRow != null) 
     { 
      ReflectionHelper.Execute(dataGridOwner, "HandleSelectionForRowHeaderAndDetailsInput", parentRow, false); 
     } 
    }   
} 

所有我们想要做的是通过虚假的(而不是真)作为方法HandleSelectionForRowHeaderAndDetailsInput的第二个参数。

我们需要通过建立我们自己的DataGridCell处理DataGrid的细胞:

public class DataGridCell : System.Windows.Controls.DataGridCell 
{ 
    static DataGridCell() 
    { 
     EventManager.RegisterClassHandler(typeof(DataGridCell), 
      UIElement.MouseLeftButtonDownEvent, 
      new MouseButtonEventHandler(DataGridCell.OnAnyMouseLeftButtonDownThunk), true); 
    } 

    private static void OnAnyMouseLeftButtonDownThunk(object sender, MouseButtonEventArgs e) 
    { 
     ((DataGridCell)sender).OnAnyMouseLeftButtonDown(e); 
    } 

    private void OnAnyMouseLeftButtonDown(MouseButtonEventArgs e) 
    { 
     bool isKeyboardFocusWithin = base.IsKeyboardFocusWithin; 
     bool flag = (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control; 
     DataGrid dataGridOwner = ReflectionHelper.GetPropertyValue<DataGrid>(this, "DataGridOwner"); 
     if (isKeyboardFocusWithin && !flag && !e.Handled && this.IsSelected) 
     { 
      if (dataGridOwner != null) 
      { 
       ReflectionHelper.Execute(dataGridOwner, "HandleSelectionForCellInput", 
        this, false, true, false); 

       if (!this.IsEditing && !this.IsReadOnly) 
       { 
        dataGridOwner.BeginEdit(e); 
        e.Handled = true; 
        return; 
       } 
      } 
     } 
     else if (!isKeyboardFocusWithin || !this.IsSelected || flag) 
     { 
      if (!isKeyboardFocusWithin) 
      { 
       base.Focus(); 
      } 
      if (dataGridOwner != null) 
      { 
       ReflectionHelper.Execute(dataGridOwner, "HandleSelectionForCellInput", 
        this, Mouse.Captured == null && flag, true, false); 
      } 
      e.Handled = true; 
     } 
    } 
} 

还需要

一个简单的 DataGridCellsPresenter

public class DataGridCellsPresenter : System.Windows.Controls.Primitives.DataGridCellsPresenter 
{ 
    protected override DependencyObject GetContainerForItemOverride() 
    { 
     return new DataGridCell(); /* the one in our namespace */ 
    } 
} 

它会说给DataGrid使用我们DataGridCell。 现在,当然,我们要创建一个默认样式(它应该被放置在Window资源)迫使DataGrid使用我们的东西:

<Style x:Key="{x:Type DataGridRow}" TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource {x:Type DataGridRow}}"> 
    <Setter Property="Control.Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type DataGridRow}"> 
       <Border Name="DGR_Border" Background="{TemplateBinding Control.Background}" BorderBrush="{TemplateBinding Control.BorderBrush}" BorderThickness="{TemplateBinding Control.BorderThickness}" SnapsToDevicePixels="True"> 
        <SelectiveScrollingGrid> 
         <SelectiveScrollingGrid.ColumnDefinitions> 
          <ColumnDefinition Width="Auto" /> 
          <ColumnDefinition Width="*" /> 
         </SelectiveScrollingGrid.ColumnDefinitions> 
         <SelectiveScrollingGrid.RowDefinitions> 
          <RowDefinition Height="*" /> 
          <RowDefinition Height="Auto" /> 
         </SelectiveScrollingGrid.RowDefinitions> 
         <DataGridCellsPresenter Grid.Column="1" ItemsPanel="{TemplateBinding DataGridRow.ItemsPanel}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" /> 
         <local:DataGridDetailsPresenter Grid.Column="1" Grid.Row="1" Visibility="{TemplateBinding DataGridRow.DetailsVisibility}" SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=AreRowDetailsFrozen, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}}" /> 
         <local:DataGridRowHeader SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" Grid.RowSpan="2" Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.Row}}" /> 
        </SelectiveScrollingGrid> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

我希望它可以帮助。

+0

感谢您的回复,但不知何故它没有效果,我需要查看解决方案什么是不正确的将再次回复,谢谢。 – Muds

+0

OnClick从未被击中:-s – Muds

+0

很奇怪:我使用VS2010(.NET 4.0)测试了我的解决方案,它可以工作。你把风格放在窗口的资源中了吗? –