我成功实现了两个DataGrids
之间的拖放,即目标DataGrid
知道选择的源DataGrid
的哪些条目,并可以将它们用于进一步处理。
现在我想确定放置鼠标的目标DataGrid
的条目。这是可能的,如果是的话,我怎样才能做到这一点?
低于我的目标DataGrid
代码:
void TargetList_Drop(object sender, DragEventArgs e)
{
var mySourceRecords =
e.Data.GetData(typeof(List<MySourceRecord>))
as List<MySourceRecord>;
// Process selected vehicle variants
... mySourceRecords should be processed here with the target DataGrid record ...
}
答案 0 :(得分:0)
您可以使用VisualTreeHelper.HitTest
Point targetPoint = e.GetPosition(DataGrid1);
HitTestResult result = VisualTreeHelper.HitTest(DataGrid1, targetPoint);
DependencyObject dropTarget = result.VisualHit;
您可以使用InputHitTest
对数据网格执行匹配测试,以确定丢弃的位置
Point targetPoint = e.GetPosition(DataGrid1);
IInputElement dropTarget = DataGrid1.InputHitTest(targetPoint);
在这些方法之后,dropTarget将成为放置的那个。现在你可以通过几种方法识别目标。
通过查找datacontext(如果元素是frameworkelement)或找到适当的父级datacontext。
答案 1 :(得分:0)
查看您的代码,目标应该是发件人,具体取决于您设置拖放的方式。那就是:
void TargetList_Drop(object sender, DragEventArgs e)
{
var target = (FrameworkElement) sender;
}
但是,您可能订阅了数据网格而不是视觉子网,因此上述内容可能对您无效。
以下附加行为可能有助于解决您的问题。我已经使用它多年了。您可以简单地在可拖动的元素上设置IsDragSource,并在可以接收丢弃的元素上设置IsDropTarget。我通常使用MVVM,所以我添加了一个DropCommand,以便它是处理drop的视图模型。
public static class DragAndDropManager
{
#region IsDragSource Attached Property
public static readonly DependencyProperty IsDragSourceProperty
= DependencyProperty.RegisterAttached("IsDragSource",typeof(bool),typeof(DragAndDropManager),new PropertyMetadata(IsDragSourceChanged));
public static void SetIsDragSource(DependencyObject d, bool value)
{
d.SetValue(IsDragSourceProperty, true);
}
public static bool GetIsDragSource(DependencyObject d)
{
return (bool)d.GetValue(IsDragSourceProperty);
}
private static void IsDragSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var element = d as FrameworkElement;
if (element == null)
return;
element.PreviewMouseMove += OnPreviewMouseMove;
}
private static void OnPreviewMouseMove(object sender, MouseEventArgs args)
{
var element = (FrameworkElement)sender;
var dragSource = args.OriginalSource as FrameworkElement;
if (args.LeftButton != MouseButtonState.Pressed
|| dragSource == null
|| dragSource.DataContext == null)
return;
var dragData = new DataObject(dragSource.DataContext);
DragDrop.DoDragDrop(element, dragData, DragDropEffects.Move);
}
#endregion
#region IsDropTarget Attached Property
public static readonly DependencyProperty IsDropTargetProperty
= DependencyProperty.RegisterAttached("IsDropTarget",typeof(bool),typeof(DragAndDropManager),new PropertyMetadata(IsDropTargetChanged));
public static void SetIsDropTarget(DependencyObject d, bool value)
{
d.SetValue(IsDropTargetProperty, true);
}
public static bool GetIsDropTarget(DependencyObject d)
{
return (bool)d.GetValue(IsDropTargetProperty);
}
private static void IsDropTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var element = d as FrameworkElement;
if (element == null)
return;
element.AllowDrop = true;
element.DragOver += OnDragOver;
element.Drop += OnDrop;
}
private static void OnDragOver(object sender, DragEventArgs e)
{
if (e.Data == null || e.Handled)
{
e.Effects = DragDropEffects.None;
return;
}
var element = (FrameworkElement)sender;
var command = GetDropCommand(element);
if (command == null)
return;
var dataFormats = e.Data.GetFormats();
if (dataFormats==null)
return;
var dragAndDropInfo = new DragAndDropInfo(element.DataContext,
e.Data.GetData(dataFormats.FirstOrDefault()));
var canDrop = dragAndDropInfo.DroppedItem != dragAndDropInfo.SourceItem
&& command.CanExecute(dragAndDropInfo);
e.Handled = true;
e.Effects = canDrop
? e.Effects = DragDropEffects.All
: DragDropEffects.None;
}
private static void OnDrop(object sender, DragEventArgs e)
{
if (e.Data == null || e.Handled)
return;
var element = (FrameworkElement)sender;
var command = GetDropCommand(element);
if (command == null)
return;
var dataFormats = e.Data.GetFormats();
if (dataFormats == null)
return;
var dragAndDropInfo = new DragAndDropInfo(element.DataContext,
e.Data.GetData(dataFormats.FirstOrDefault()));
var canDrop = dragAndDropInfo.DroppedItem != dragAndDropInfo.SourceItem
&& command.CanExecute(dragAndDropInfo);
if (canDrop)
{
command.Execute(dragAndDropInfo);
}
e.Handled = true;
}
#endregion
#region DropCommand Attached Property
public static readonly DependencyProperty DropCommandProperty
= DependencyProperty.RegisterAttached("DropCommand",typeof(ICommand),typeof(DragAndDropManager),new PropertyMetadata(DropCommandProperty));
public static void SetDropCommand(DependencyObject d, ICommand value)
{
d.SetValue(DropCommandProperty, value);
}
public static ICommand GetDropCommand(DependencyObject d)
{
return (ICommand)d.GetValue(DropCommandProperty);
}
#endregion
}
public class DragAndDropInfo
{
public object SourceItem { get; private set; }
public object DroppedItem { get; private set; }
public DragAndDropInfo(object sourceItem, object droppedItem)
{
SourceItem = sourceItem;
DroppedItem = droppedItem;
}
}
}
以下示例XAML用于TreeView示例。在你的情况下,你可以在行演示者等上做类似的事情
<TreeView
Behaviors:DragAndDropManager.IsDropTarget="true"
Behaviors:DragAndDropManager.DropCommand="{Binding DropCommand}">
<TreeView.Resources>
<Style TargetType="TreeViewItem">
<Style.Setters>/>
<Setter Property="Behaviors:DragAndDropManager.IsDragSource" Value="true"/>
<Setter Property="Behaviors:DragAndDropManager.IsDropTarget" Value="true"/>
<Setter Property="Behaviors:DragAndDropManager.DropCommand" Value="{Binding DropCommand}"/>
</Style.Setters>
</Style>
</TreeView.Resources>
</TreeView>