WPF拖拽 - DragLeave什么时候开火?

时间:2011-03-27 04:48:09

标签: .net wpf vb.net

从父级控件拖动到子控件时,我收到了DragLeave事件。我只希望在超出控件范围时获得此事件。我该如何实现呢?

请参阅这个简单的示例应用程序。

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <TextBox Height="50" >Hilight and Drag this text</TextBox>
        <Border BorderBrush="Blue" BorderThickness="2">
            <StackPanel AllowDrop="True" Name="Stack" >
                <Label >If I drag text across the gray line, Stack.DragLeave will fire.</Label>
                <Separator></Separator>
                <Label>I only expect to get this event when leaving the blue rectangle. </Label>
            </StackPanel>
        </Border>
        <TextBlock >Stack.DragLeave Count: <Label x:Name="countLabel" /></TextBlock>
    </StackPanel>
</Window>

并在

背后的代码中
Class MainWindow

    Private Sub Stack_DragLeave(ByVal sender As Object, ByVal e As System.Windows.DragEventArgs) Handles Stack.PreviewDragLeave
        countLabel.Content = countLabel.Content + 1
    End Sub

End Class

enter image description here

1 个答案:

答案 0 :(得分:17)

我最近一直在研究我自己的应用程序,它正在广泛使用WPF拖放,在你看到的完全相同的问题上花了半天时间(调试,谷歌搜索,重新阅读文档)后,我只能得出结论在WPF库中埋藏的“未来增强”。

  

拖放系统似乎有一个怪癖。当用户将对象拖过我们的控件时,系统会显然会经常向我们发送DragLeave个事件,紧接着是DragEnter个事件。因此,当我们得到DragLeave时,我们无法确定拖放操作是否实际终止。因此,我们不是立即进行清理,而是安排清理稍后执行,如果在此期间我们收到另一个DragEnterDragOver事件,那么我们就不会进行清理。

这是我的解决方案:

protected virtual void OnTargetDragLeave(object sender, DragEventArgs e)
{
    _dragInProgress = false;

    _target.Dispatcher.BeginInvoke( new Action( ()=> 
    {
        if( _dragInProgress == false ) OnRealTargetDragLeave( sender, e ); 
    } ) );
}

protected virtual void OnTargetDragOver(object sender, DragEventArgs e)
{
    _dragInProgress = true;

    OnQueryDragDataValid( sender, e );
}