我正在尝试编写一些通用代码来处理WPF丢弃目标中的丢弃 . AllowDrop
设置为true,我已经连接到放置目标UIElement上的 DragEnter
, DragOver
, DragLeave
和 Drop
. 使用冒泡事件可以嵌套放置目标 .
注意:我无法访问拖动源 - 这是应用程序间拖放 .
如果我有一些UI清理要在潜在的丢弃结束时执行,并且用户按Esc取消掉落,则放置目标似乎永远不会得到一个特定的事件,我可以区别于所有其他事件 . 丢弃很容易,但什么表示取消?
我遇到的问题是:
-
DragLeave
是一个冒泡的路线事件 .
始终通过命中测试为此事件(以及相应的预览)设置 -
e.OriginalSource
. -
目标是
ItemsControl
(列表框是我目前正在测试的) .
当我拖过我想要的放置目标时,我会从目标中的子视觉效果中获得大量的 DragLeave
事件 . 我从来没有从目标本身得到任何东西 . 网格,矩形,边框,文本块,它们都很高兴地发送给我 DragLeave
,但实际上没有一个'm connected up to. I thought it might be a hit-testing problem, but I'将 ItemsControl
的背景设置为一种颜色,它没有任何区别 .
我错过了什么?我怎么能确定放下操作已经完成了?
(我试图解决的实际问题是,我在TreeView中实现了一些自定义拖动行为,当您将鼠标悬停在文件夹上时会扩展文件夹,并在删除完成后取消计时器并取消扩展,以及更多内容,但我甚至无法为ListBox明智地触发事件 .
2 回答
你确实有一个复杂的场景,所以这将开始基本,希望给你一个方向,并希望有一个解决方案 .
如果控件标记为AllowDrop = true,则框架将仅通知DragEnter事件 . 所以一定要确保你做到了 . 这听起来像你有,但我只是想确定 .
我不确定你为什么需要DragLeave事件,但是如果要获取所选数据,最简单的获取数据的方法不是挂钩到DragLeave而是挂钩到PreviewMouseMove . 然后,您可以在执行DoDragDrop之前确定是否按下鼠标以及移动距离的距离 .
在这种情况下,您还可以添加和分析拖动数据 . 拖动开始时,您可以创建一个新的DataObject并使用DoDragDrop调用发送它:
现在可以通过使用DragEventArgs对象访问此拖动数据(如果不重命名事件参数,则为e):
我的建议是向拖动事件数据添加一些独特的信息,以根据数据区分事件 . 列表框选择中的数据项,或者包含数据项的新类和其他指示符(如果需要) .
检查 e.Source 而不是e.OriginalSource,如果你在ItemsControl上设置DropTarget = "True"并且你有DropOver事件附加到ItemsControl,则事件参数e.Source应该是ItemsControl .