こんにちはにWPFのデータグリッドで選択した方法を停止しない私は、私はどのように停止することができます私はドラッグはすべて、これは些細に聞こえるかもしれないが、私はドラッグを停止したい
のような単純なグリッドを持ってWPF
DataGrid
で選択クリックしてドラッグすると複数選択できますが、ShiftキーとCtrlキーで複数選択することができます。ハック
おかげ
こんにちはにWPFのデータグリッドで選択した方法を停止しない私は、私はどのように停止することができます私はドラッグはすべて、これは些細に聞こえるかもしれないが、私はドラッグを停止したい
のような単純なグリッドを持ってWPF
DataGrid
で選択クリックしてドラッグすると複数選択できますが、ShiftキーとCtrlキーで複数選択することができます。ハック
おかげ
てみてください。DataGrid
を継承するクラスを作成し、DataGrid
制御が選択ジェスチャーをカスタマイズするために設計されていませんbase.OnMouseMove
を呼び出すことなくを上書きするには、とにかくいくつかのハッキングが到達するために行うことができますターゲット。我々はヘルパークラスに必要なすべての まず:
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);
}
}
を私はそれが好きではありませんが、反射が必要とされています。まず、私たちはそのOnClick
コードを変更するために私たち自身のDataGridRowHeader
で順序を作成するために必要なすべての:
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
の2番目のパラメータとして(代わりに、真の)虚偽を渡すことです。私たちは、私たち自身の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 */
}
}
それは私たちのDataGridCell
を使用するDataGrid
に言うだろう。 さて、もちろん、私たちは私たちのものを使用するようにDataGrid
を強制するために(それがWindow
リソースに配置する必要があります)、デフォルトのスタイルを作成する必要があります。
<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>
私はそれに役立つことを願って。
それはドラッグのドロップ動作を打ち消すので、 – Muds
を追加して、ドラッグドロップの場合は – Mikolaytis
以上の汚れを確認してください。 – Muds