Reputation: 18
I am trying to drag an item from one Canvas to another. I want an event to fire when the object enters the other Canvas. None of the Drag events seem to fire. I have tried following the solution for this question, but it does not work for me: Drag and Drop not responding as expected
My canvas is this:
<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>
If I do not have the Panel.ZIndex="-1" then the rectangle is dragged underneath the mainCanvas. This is true even if I set the ZIndex for the rectangle to some positive value.
My code is the following, modified by examples I have found:
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
}
}
}
Upvotes: 0
Views: 2981
Reputation: 132548
I believe it's because you're capturing the mouse, so all mouse events are being handled by your dragged Rectangle
, and they don't get passed on to your Canvas
I personally had all kinds of problems with using WPF's built-in drag/drop functionality, so I ended up using MouseEvents
instead.
The solution I used was from this answer, and went like this:
On MouseDown
with left button down, record the position (on MouseLeave
erase the position)
On MouseMove
, if left button down, position is recorded, and current mouse position differs by more than delta, set a flag saying drag operation is in progress & have your application (not the dragged object) capture the mouse
On MouseMove
with drag operation in progress, use hit testing to determine where your rectangle should be (ignoring the rectangle itself) and adjust its parenting and position accordingly.
On MouseUp
with drag operation in progress, release the mouse capture and clear the "drag operation is in progress" flag
Upvotes: 0
Reputation: 2618
You're not dragging anything actually, just moving rectangle here and there in canvas.
You'll need to call DragDrop.DoDragDrop
function when your rectangle leave the source, also detach it from source so that you can add it to target later.
// 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
....
Upvotes: 2