2016-07-05 64 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)測試了我的解決方案,它可以工作。你把風格放在窗口的資源中了嗎? –