gpt4 book ai didi

wpf - DragDrop - DragEnter/DragLeave 事件持续触发

转载 作者:行者123 更新时间:2023-12-03 23:31:21 28 4
gpt4 key购买 nike

我在 Canvas 上有一个拖放操作,当一个对象被拖入和拖出它时,它应该做一些事情。我的问题是 DragEnter/DragLeave 事件在鼠标将对象移动到它上面时不断触发,而不仅仅是在进入/退出时。鼠标移动得越快,事件触发的频率就越高。

Canvas DragOver 事件移动了被拖拽对象的 Canvas.Top/Left,我认为这可能是我的问题,但我不确定如何解决这个问题。

最佳答案

以下是事件的顺序:

  • 您的鼠标从您在面板上单击它的位置移动。没有事件触发。
  • 您的鼠标到达面板的边缘并进入 Canvas 。 DragEnter事件在 Canvas 上触发。
  • 您的 DragEnter处理程序移动面板,使其现在位于鼠标下方。由于鼠标不再在 Canvas 上(它在面板上),DragLeave事件触发。
  • 您的鼠标移动得更远,再次到达面板的边缘。重复步骤 2 和 3。

  • 您移动鼠标的速度越快,您收到的事件就越多。

    您的问题的本质是拖放使用 HitTest ,并且通过移动您的面板,您正在击败 HitTest 的能力,以查看面板“后面”以了解它被放入哪个容器。

    解决办法是使用自己的代码进行拖放处理,其实一点都不难。 WPF 的 HitTest 引擎足够强大,可以在当前对象后面进行 HitTest ,但拖放不使用此功能。但是,您可以通过使用 VisualTreeHelper.HitTest 直接使用它。需要 HitTestFilterCallback 的过载和一个 HitTestResultCallback .只需传递一个过滤器,忽略被拖动面板内的任何点击。

    我发现对于您描述的场景,通过处理鼠标事件进行拖放实际上比使用内置的 DoDragDrop 更容易,因为您不必处理复杂性(DataObject、DragDropEffects、QueryContinueDrag 等)。这种额外的复杂性对于启用在应用程序和进程之间拖动的场景非常重要,但对您正在做的事情没有帮助。

    这是简单的解决方案:
  • 在 MouseDown 上按下左键,记录位置(在 MouseLeave 上删除位置)
  • 在 MouseMove 上,{左键按下,位置记录,当前鼠标位置相差超过 delta} 设置一个标志,表示正在进行拖动操作并捕获鼠标
  • 在正在进行拖动操作的 MouseMove 上,使用 HitTest 来确定您的面板应该在哪里(忽略面板本身)并相应地调整其父级和位置。
  • 在正在进行拖动操作的 MouseUp 上,释放鼠标捕获并清除“正在进行拖动操作”标志

  • 享受。

    关于wpf - DragDrop - DragEnter/DragLeave 事件持续触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2632821/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com