2011-03-27 46 views
14

從父級拖動到子級控件時,我得到了DragLeave事件。我只希望在控制範圍外移動時得到這個事件。我怎樣才能實現這個?WPF拖放 - 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

+0

[的DragDrop - dragEnter事件/ DragLeave事件持續開火]的可能重複(http://stackoverflow.com/questions/2632821/dragdrop-dragenter-dragleave-events-keep - 發射) – 2015-08-11 19:29:55

回答

17

我最近一直在我自己的應用程序正在使用WPF拖/廣泛下降的代碼,並半天花後(調試,谷歌搜索,重新閱讀文檔)在你看到完全相同的問題,我只能得出結論,有一個「未來增強」埋在WPF庫中的某處。

這是我的解決方案:

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

     // It appears there's a quirk in the drag/drop system. While the user is dragging the object 
     // over our control it appears the system will send us (quite frequently) DragLeave followed 
     // immediately by DragEnter events. So when we get DragLeave, we can't be sure that the 
     // drag/drop operation was actually terminated. Therefore, instead of doing cleanup 
     // immediately, we schedule the cleanup to execute later and if during that time we receive 
     // another DragEnter or DragOver event, then we don't do the cleanup. 
     _target.Dispatcher.BeginInvoke(new Action(()=> { 
           if(_dragInProgress == false) OnRealTargetDragLeave(sender, e); })); 
    } 

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

     OnQueryDragDataValid(sender, e); 
    } 
+0

感謝DXM,這似乎解決了絕大多數兒童控制的問題。但是,拖動分隔符控件(也可能是其他)會導致調用OnQueryDragDataValid方法。 – PeterM 2011-03-27 13:53:55

+1

@Peter,我在那裏添加的OnQueryDragDataValid()的調用是爲了我的具體實現。我不認爲它需要在那裏,如果你不需要它。我的設計(我認爲WPF也希望這樣)是OnQueryDragDataValid()可以被調用任意次數,並且您只需要驗證drop操作是否有效。 – DXM 2011-03-28 06:35:00

+0

@DMX,是的,你是絕對正確的。我的意思是編寫OnRealTargetDragLeave拖動分隔符控件時觸發。我相信這是因爲「分隔符控件不響應任何鍵盤,鼠標,鼠標滾輪或平板電腦輸入,並且無法啓用或選擇(來自MSDN)」。但是,分隔符可以很容易地用其他類似的控件(線條,矩形等)替換,這些控件都可以工作。再次感謝偉大的解決方法! – PeterM 2011-03-29 02:53:10