如何从wpf开始检测拖动

ΦXo*_*a ツ 3 c# wpf user-interface drag-and-drop

我从这个问题知道如何处理拖放

/sf/answers/1251100021/

但我无法检测拖动事件何时开始,因此我可以准备一些资源......

如果我打印这些事件,则首先出现“Drop”,然后出现“Drag”。

如何干净地处理这个问题

我的代码很简单

    private void Label_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        var lbl = (Label)sender;
        DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Move);
        Console.WriteLine("Drag...");
    }

    private void Label_Drop(object sender, DragEventArgs e)
    {
        Console.WriteLine("Drop...");
    }

    private void Label_DragEnter(object sender, DragEventArgs e)
    {
        Console.WriteLine("Label_DragEnter...");
    }

    private void Label_DragLeave(object sender, DragEventArgs e)
    {
        Console.WriteLine("Label_DragLeave...");
    }
Run Code Online (Sandbox Code Playgroud)

Azz*_*ziz 5

长话短说:如果您想在删除标签之前准备资源,请在调用DragDrop方法之前或在OnPreviewMouseDown事件中编写该代码。


很长的故事:

使用Snoop,我能够查看拖动标签时触发的事件。

看来唯一触发的事件是PreviewMouseDownMouseDown

在此输入图像描述

所以我们应该只实现这些事件。

private void Lbl_OnMouseDown(object sender, MouseButtonEventArgs e)
{
    var lbl = (Label)sender;
    DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Move);
    Console.WriteLine("Drag...");
}

private void UIElement_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    Console.WriteLine("Label_PreviewMouseDown...");
}
Run Code Online (Sandbox Code Playgroud)

这将导致在开始拖动标签时首先打印“Label_PreviewMouseDown...”,并在标签完成拖动时首先打印“Drag...”。

在此输入图像描述

然而,这并不是完整的事实。

让我们稍微修改一下我们的代码。让我们添加DateTime.Now.Second测试消息何时实际触发。然后,我将拖动标签几秒钟,然后将其放下以查看打印到控制台的顺序。

private void Lbl_OnMouseDown(object sender, MouseButtonEventArgs e)
{
    var lbl = (Label)sender;

    Console.WriteLine("Label_OnMouseDown_BeforeDragging..." + DateTime.Now.Second);

    DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Move);

    Console.WriteLine("Label_OnMouseDown_AfterDragging..." + DateTime.Now.Second);
}

private void UIElement_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    Console.WriteLine("Label_PreviewMouseDown..." + DateTime.Now.Second);
}
Run Code Online (Sandbox Code Playgroud)

现在让我们再次尝试拖动。

在此输入图像描述

事实证明这OnMouseDown发生在你完成拖动之前。该DoDragDrop方法会暂停代码,直到您放下标签,然后您就可以继续并打印到控制台。

因此:如果您想在删除标签之前准备资源,请在调用方法之前DragDrop或在OnPreviewMouseDown事件中编写该代码。

希望这可以帮助。