views:

712

answers:

2

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?

+5  A: 

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.

Aaronaught
1. Talking about the drag scope to the entire window, its merely a check to cancel the drag if the mouse drags it out of the window.2. My question specifically says that the entire GiveFeedback must be commented out.3. I do understand that it is the drop target that specifies whether to accept the data or not. Drop target uses its DragOver event to specify whether or not to accept the drop by setting args.Effects = DragDropEffects.None. It may also set Copy or Move effects, if that's the case.4. DragSource can still specify allowed effects in DragDrop.DoDragDrop() call.
Trainee4Life
5. The code is not being used in production. It was one of the samples I studied when I created the drag drop framework in our application.
Trainee4Life
Please read the question again, if you can reproduce what I say then you would be in a better position to answer.
Trainee4Life
Please see my edit. This should be what you're looking for.
Aaronaught
Apologies for a late reply, I did read your answer but didn't get the time to check it. Anyways, I think it should solve the problem. I'll let you know when I try it. And thanks for taking the time.. :)
Trainee4Life
A: 

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 :)

Luke Machowski