2012-07-03 37 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

嗨, 我只用它们的默认方式使用事件 - 因此我无法从你写的内容中搜集正确的结构。你(或者其他)是否知道如何在另一个上下文中捕获事件的一些参考? (升级事件?)我仍然希望能够在可能相同的多个元素中获取单个移动元素(并重叠拖动的元素)。再次感谢你。 –