放下目标如何检测取消的拖拽; WPF下降?

时间:2011-10-28 14:39:50

标签: wpf drag-and-drop

我正在尝试编写一些通用代码来处理WPF丢弃目标中的丢弃。 AllowDrop设置为true,我已经联系到DragEnterDragOverDragLeave和&放置目标UIElement上的Drop。使用冒泡事件可以嵌套放置目标。

注意:我无法访问拖动源 - 这是应用程序间的拖动和放大器。下降。

如果我有一些UI清理要在潜在的丢弃结束时执行,并且用户按Esc取消掉落,则放置目标似乎永远不会得到一个特定的事件,我可以区别于所有其他事件。丢弃很容易,但什么表示取消?

我遇到的问题是:

  • DragLeave是一个冒泡的路线事件。
  • e.OriginalSource始终通过hittesting为此事件(以及相应的预览)设置。
  • 目标是ItemsControl(列表框是我目前正在测试的内容)。

当我拖动我想要的放置目标时,我会从目标中的子视觉效果中获得大量DragLeave个事件。 我从来没有从目标本身得到任何东西。网格,矩形,边框,文本块,他们都很高兴地发送给我DragLeave,但没有一个来自实际的ItemsControl我已连接取决于。我认为这可能是一个热门测试问题,但我已将ItemsControl的背景设置为一种颜色,并没有区别。

我错过了什么?我怎么能确定放下操作已经完成了?

(我试图解决的实际问题是我在TreeView中实现了一些自定义拖动行为,当您将鼠标悬停在文件夹上时会扩展文件夹,并且当放置完成时取消定时器并撤消扩展,并且还有更多,但我甚至无法为ListBox明智地触发事件。

2 个答案:

答案 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。