Dot-Net

WPF 拖放 - DragLeave 何時觸發?

  • June 20, 2018

從父控制項拖動到子控制項時,我收到 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

在此處輸入圖像描述

我最近一直在開發自己的應用程序,該應用程序廣泛使用 WPF 拖放,並且在您看到完全相同的問題上花了半天時間(調試、Google搜尋、重新閱讀文件)之後,我只能得出結論:“未來增強”埋在 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 );
}

引用自:https://stackoverflow.com/questions/5447301