我正在尝试编写一些通用代码来处理WPF丢弃目标中的丢弃。 AllowDrop
设置为true,我已经联系到DragEnter
,DragOver
,DragLeave
和&放置目标UIElement上的Drop
。使用冒泡事件可以嵌套放置目标。
注意:我无法访问拖动源 - 这是应用程序间的拖动和放大器。下降。
如果我有一些UI清理要在潜在的丢弃结束时执行,并且用户按Esc取消掉落,则放置目标似乎永远不会得到一个特定的事件,我可以区别于所有其他事件。丢弃很容易,但什么表示取消?
我遇到的问题是:
DragLeave
是一个冒泡的路线事件。e.OriginalSource
始终通过hittesting为此事件(以及相应的预览)设置。ItemsControl
(列表框是我目前正在测试的内容)。当我拖动我想要的放置目标时,我会从目标中的子视觉效果中获得大量DragLeave
个事件。 我从来没有从目标本身得到任何东西。网格,矩形,边框,文本块,他们都很高兴地发送给我DragLeave
,但没有一个来自实际的ItemsControl
我已连接取决于。我认为这可能是一个热门测试问题,但我已将ItemsControl
的背景设置为一种颜色,并没有区别。
我错过了什么?我怎么能确定放下操作已经完成了?
(我试图解决的实际问题是我在TreeView中实现了一些自定义拖动行为,当您将鼠标悬停在文件夹上时会扩展文件夹,并且当放置完成时取消定时器并撤消扩展,并且还有更多,但我甚至无法为ListBox明智地触发事件。
答案 0 :(得分:0)
你确实有一个复杂的场景,所以这将开始基础,希望能给你一个方向,并希望有一个解决方案。
如果控件标记为AllowDrop = true,框架将仅通知DragEnter事件。所以一定要确保你做到了。这听起来像你有,但我只是想确定。
我不确定你为什么需要DragLeave事件,但是如果要获取所选数据,获取数据的最简单方法就是不要挂钩到DragLeave,而是挂钩到PreviewMouseMove。然后,您可以在执行DoDragDrop之前确定是否按下鼠标以及移动距离的距离。
在这种情况下,您还可以添加和分析拖动数据。拖动开始时,您可以创建一个新的DataObject并使用DoDragDrop调用发送它:
private static void listBox_PreviewMouseMove(object sender, MouseEventArgs e)
{
// Get the current mouse position
var mousePos = e.GetPosition(null);
var diff = startPoint - mousePos;
if (canScroll && e.LeftButton == MouseButtonState.Pressed &&
(Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
{
var dataObject = (from lbi in startList.Items.Cast<object>().Select((t, i) => (ListBoxItem)startList.ItemContainerGenerator.ContainerFromIndex(i)) where lbi != null && lbi.IsSelected select Convert.ToString(lbi.Content)).ToList();
// Initialize the drag & drop operation
var listBoxData = new ListBoxData(){ StartList = startList, Data = dataObject};
var dragData = new DataObject("listBoxData", listBoxData);
System.Windows.DragDrop.DoDragDrop(startList, dragData, DragDropEffects.Move);
}
}
现在可以通过使用DragEventArgs对象访问此拖动数据(如果不重命名事件参数,则为e):
e.Data.GetData("listBoxData")
我的建议是在拖动事件数据中添加一些独特的信息,以根据数据区分事件。列表框选择中的数据项,或者包含数据项的新类,以及需要时的其他指示符。
答案 1 :(得分:0)
检查 e.Source 而不是e.OriginalSource,如果您在ItemsControl&amp;上设置了DropTarget =“True”。你有DropOver事件附加到ItemsControl,事件参数e.Source应该是ItemsControl。