2012-07-03 38 views
0

我正試圖將一個項目從一個畫布拖到另一個畫布。當對象進入其他畫布時,我想要觸發一個事件。沒有一個Drag事件似乎觸發。 我已經嘗試了這個問題解決之後,但它不爲我工作: Drag and Drop not responding as expected兩個畫布之間的WPF DragEnter沒有觸發

我的畫布是這樣的:

<Window x:Class="DragEnterTest.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="DragEnterMainWindow" Height="460" Width="1000"> 
<Grid> 
    <Canvas Name="Toolbox" Background="Beige" Height="400" Width="200" Margin="12,12,800,35"> 
     <Rectangle Name="dragRectangle" Canvas.Left="0" Canvas.Right="0" Width="50" Height="50" Fill="Red" 
        MouseLeftButtonDown="dragRectangle_MouseLeftButtonDown" 
        MouseLeftButtonUp="dragRectangle_MouseLeftButtonUp" 
        MouseMove="dragRectangle_MouseMove" 
        /> 
    </Canvas> 
    <Canvas Background="Azure" Height="400" Margin="218,12,0,35" Name="mainCanvas" Panel.ZIndex="-1" 
      DragEnter="mainCanvas_DragEnter" 
      DragLeave="mainCanvas_DragLeave" 
      PreviewDragEnter="mainCanvas_PreviewDragEnter" 
      PreviewDragLeave="mainCanvas_PreviewDragLeave" 
      AllowDrop="True" 
      DragDrop.Drop="mainCanvas_Drop" 
      /> 
</Grid> 
</Window> 

如果我沒有Panel.ZIndex =「 - 1 「然後將矩形拖到mainCanvas下面。即使我將矩形的ZIndex設置爲某個正值,情況也是如此。

我的代碼如下,用實例修改,我發現:

namespace DragEnterTest 
{ 
/// <summary> 
/// Interaction logic for MainWindow.xaml 
/// </summary> 
public partial class MainWindow : Window 
{ 
    private bool _isRectDragInProg; 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void dragRectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     _isRectDragInProg = true; 
     dragRectangle.CaptureMouse(); 
    } 

    private void dragRectangle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     _isRectDragInProg = false; 
     dragRectangle.ReleaseMouseCapture(); 
    } 

    private void dragRectangle_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (!_isRectDragInProg) return; 
     // get the position of the mouse relative to the Canvas 
     var mousePos = e.GetPosition(Toolbox); 

     // center the rect on the mouse 
     double left = mousePos.X - (dragRectangle.ActualWidth/2); 
     double top = mousePos.Y - (dragRectangle.ActualHeight/2); 
     Canvas.SetLeft(dragRectangle, left); 
     Canvas.SetTop(dragRectangle, top); 
    } 

    private void mainCanvas_DragEnter(object sender, DragEventArgs e) 
    { 
     string t = "Test"; // Never enters this event 
    } 

    private void mainCanvas_DragLeave(object sender, DragEventArgs e) 
    { 
     string t = "Test"; // Never enters this event 
    } 

    private void mainCanvas_PreviewDragEnter(object sender, DragEventArgs e) 
    { 
     string t = "Test"; // Never enters this event 
    } 

    private void mainCanvas_PreviewDragLeave(object sender, DragEventArgs e) 
    { 
     string t = "Test"; // Never enters this event 
    } 

    private void mainCanvas_Drop(object sender, DragEventArgs e) 
    { 
     string t = "Test"; // Never enters this event 
    } 
} 

}

回答

2

你沒有任何拖實際上,這裏只是有移動矩形,並在畫布上。

當矩形離開源時,您需要調用DragDrop.DoDragDrop函數,也可以將它從源代碼中分離出來,以便稍後將其添加到目標中。

// Drag - In mousemove event when mouse has gone out of toolbox 
    DragDrop.DoDragDrop(
     Toolbox, 
     new DataObject("MyWPFObject", rectangle), 
     DragDropEffects.Move 
    ); 

    // Drop - In Drop event of target 
    if (e.Data.GetDataPresent("MyWPFObject")) 
    { 
     var rectangle = e.Data.GetData("MyWPFObject") as Rectangle 
    .... 

Tutorial ...

+0

謝謝您的快速答覆。 我還沒有得到它與我真正想要的工作(我的例子很簡單)。看來我必須自己編寫很多代碼。但是你的簡單解釋非常好,讓我更加了解什麼是拖拽(在WPF中)。爲此,我感謝你。 –

0

我相信這是因爲你捕獲鼠標,讓所有的鼠標事件都被你拖累Rectangle處理,他們沒有得到傳達到Canvas

我個人有使用WPF的內置拖放功能的各種問題,所以我最終使用MouseEvents來代替。

我所用的是從this answer,去這樣的解決方案:

  1. MouseDown按左鍵下來,記錄位置(MouseLeave擦除位置)

  2. MouseMove,如果左鍵向下,位置被記錄,並且當前鼠標位置相差大於三角洲,設置一個標誌說拖動操作正在進行中&有你的應用程序(不是拖動的物體)捕獲鼠標

  3. MouseMove正在進行拖動操作時,使用命中測試來確定您的矩形應該在哪裏(忽略矩形本身)並相應地調整其父母和位置。

  4. MouseUp與正在進行拖拽操作,釋放鼠標捕獲和清除「拖動操作正在進行」標誌

+0

嗨Rachel,謝謝你的回答。 我不明白你的第三點提到的小組。你的意思是矩形,還是有一些我不知道的面板? 另外你的第二點:讓你的應用程序捕捉鼠標:你有一些例子嗎?我不知道你在這裏的意思。 在真正的程序中,我創建了一個看起來一樣的對象,但它有自己的事件,而且這個對象是我拖放的(但只有當它落在正確的畫布上時,否則它應該消失) 。 –

+0

@ user1497953對不起,應該是'Rectangle'而不是'Panel'。我會更新它。此外,您當前的代碼具有拖動的「Rectangle」捕獲鼠標,因此任何鼠標事件都只能由「Rectangle」對象處理。我正在瀏覽一些我的舊代碼,並且我有一個註釋掉了所有鼠標捕獲語句,另一個使用'e.MouseDevice.Capture(this作爲IInputElement);''其中'e'來自一個MouseEventArgs' 'MouseMove'事件,'this'是'Application.Current.MainWindow' – Rachel

+0

嗨, 我只用它們的默認方式使用事件 - 因此我無法從你寫的內容中搜集正確的結構。你(或者其他)是否知道如何在另一個上下文中捕獲事件的一些參考? (升級事件?)我仍然希望能夠在可能相同的多個元素中獲取單個移動元素(並重疊拖動的元素)。再次感謝你。 –