Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net WPF拖放-DragLeave何时点火?_.net_Wpf_Vb.net - Fatal编程技术网

.net WPF拖放-DragLeave何时点火?

.net WPF拖放-DragLeave何时点火?,.net,wpf,vb.net,.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="MainW

从父控件拖动到子控件时,我将获得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>

我最近一直在开发我自己的应用程序,该应用程序广泛使用WPF拖放功能,在花了半天时间(调试、搜索、重新阅读文档)处理您看到的完全相同的问题后,我只能得出结论,WPF库中的某个地方隐藏着一个“未来增强”

看起来拖放系统有一个怪癖。当用户将对象拖动到我们的控件上时,系统似乎会非常频繁地向我们发送
DragLeave
事件,紧接着是
DragEnter
事件。因此,当我们获得
DragLeave
时,我们无法确定拖放操作是否已实际终止。因此,我们不立即进行清理,而是安排稍后执行清理,如果在此期间我们收到另一个
DragEnter
DragOver
事件,则我们不进行清理

这就是我的解决方案:

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 );
}

感谢DXM,这似乎解决了绝大多数儿童控件的问题。但是,拖动分隔符控件(可能还有其他控件)会导致调用OnQueryDragDataValid方法。@Peter,我在其中添加的对OnQueryDragDataValid()的调用是为了我的特定实现。如果你不需要它,我想它不需要在那里。我的设计(我认为WPF也希望如此)是OnQueryDragDataValid()可以被调用任意次数,您只需验证drop操作是否有效。@DMX,是的,您完全正确。我想写的是,当拖动分隔符控件时,OnRealTargetDragLeave会触发。我认为这是因为“分隔符控件不会对任何键盘、鼠标、鼠标滚轮或平板电脑输入做出反应,并且无法启用或选择(来自MSDN)”。但是,分隔符可以很容易地替换为其他类似的控件(直线、矩形等)。再次感谢您的出色工作@DXM我也尝试了按钮、标签和矩形的解决方案,但我的dragLeave事件仍然会触发。我该怎么办?@DMX。谢谢你,先生!我发现在OnDragOver之前要调用OnDragEnter方法。因此,我还在OnDragEnter中添加了
\u dragInProgress=true
。工作起来很有魅力!可能重复的
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 );
}