Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is drop allowed even if Effects = DragDropEffects.None is set?

Dragging happens from "source" to "target". When the source calls DoDragDrop() with allowedEffects as DragDropEffects.Copy, then I'm able to cancel the drop by setting Effects = DragDropEffects.None at the target (in DragOver event).

But the same situation fails when I set my allowedEffects as DragDropEffects.Move.

To reproduce the situation, download the sample from http://jaimersamples.members.winisp.net/samples/dragdrop/drag.zip

Change line.. (to DragDropEffects.Move)

DragDrop.DoDragDrop(this.DragSource, data, DragDropEffects.Copy);

Add line..

void Window1_DragOver(object sender, DragEventArgs args)
{
   args.Effects = DragDropEffects.None;

And also comment out the entire, DragSource_GiveFeedback..

void DragSource_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
    //System.Diagnostics.Debug.WriteLine("DragSource_GiveFeedback " + e.Effects.ToString());

Is there some kind of bug in the framework, or am I just not able to see something obvious?

like image 381
Trainee4Life Avatar asked Dec 11 '09 13:12

Trainee4Life


2 Answers

After going over your comments and your code again, with some effort I was able to understand and reproduce the problem you are talking about.

What you're missing is the line:

e.Handled = true;

In your Window1_DragOver event. Add that and it will work the same for both DragDropEffects.Move and DragDropEffects.Copy.

Why it worked for DragDropEffects.Copy without setting e.Handled in the first place is anyone's guess. Undocumented conditions lead to undocumented behaviour.

I'm going to very strongly recommend that next time you post a code sample containing the minimum possible code to reproduce the problem. I apologize for the original confusion, but nevertheless it was very hard to figure out what was going on in this one.

like image 77
Aaronaught Avatar answered Oct 31 '22 21:10

Aaronaught


I think the question was answered well above but I just thought that this was a valuable lesson that I learnt when doing drag and drop...

The initial DragDropEffect that is passed to the DoDragDrop method should be considered as a suggestion (or a desire) for what operation should be performed. If I remember correctly, that method returns the actual effect that the target performed if the drag and drop was actually successful (and not cancelled).

This creates a simple communication protocol between the source and destination and is mainly useful for cases when there are several potential targets for the drag. It allows you to distinguish what actually happened. This is particularly useful to think about because you might be interacting with a component that you don't even know about or expect. If you take this into account, you can sometimes get surprising benefits where drag and drop becomes more useful that was originally planned for because suddenly other components can interoperate without any other explicit coding.

With this being said, I would imagine that it makes sense for the .net framework to treat copy and move operations differently by default because the one operation is constructive and the other is destructive. I think they are trying to protect from unwanted destructive operations from occurring without being handled explicitly. Not sure of this but just a thought :)

like image 22
Luke Machowski Avatar answered Oct 31 '22 22:10

Luke Machowski