Monday, October 23, 2006

DragDropEffects.Link bit not included in DragDropEffects.All value (.Net 2.0)

I just spent a frustrating few minutes trying to figure out what looked to me like some unexpected behavior in the code (C# 2.0) for a drag/drop operation in a Windows Forms component. In the handler for a DragOver event, I was setting the Effect property of the DragEventArgs argument to DragDropEffects.Link, but then subsequently in my GiveFeedback event handler, the Effect property of the GiveFeedbackEventArgs was coming back as None.

In other words, I was essentially doing this in my DragOver event handler:

private void HandleDragOver(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Link;
}

And then seeing this result in my GiveFeedback event handler:

private void HandleGiveFeedback(object sender,
  GiveFeedbackEventArgs e)
{
    if (e.Effect == DragDropEffects.Link)
    {
        // (Execution not making it here -- value of 
        // e.Effect is DragDropEffects.None!)
    }
}

I figured out that the problem was that I was using this line of code to start the drag operation:

DoDragDrop(dragData, DragDropEffects.All);

See the problem? I didn't, at first.

The DragDropEffects enumeration is a FlagsAttribute enum with the following members: All, Copy, Link, Move, Scroll, and None. At the time that I coded the DoDragDrop line of code above, I had made the assumption that the All value of the enumeration was defined as:

Copy | Link | Move | Scroll

That is, a bitwise OR combination of all of the members of the enum aside from the None member.

However, looking that the value of System.Windows.Forms.DragDropEffects.All in the Visual Studio debugger, the value is actually defined as:

Copy | Move | Scroll

The Link member is not present! This is why my GiveFeeback event handler was failing to recognize DragDropEffects values of Link -- Link was not actually being specified in the allowedEffects parameter (argument 2) of my DoDragDrop call.

Since what I really wanted to accomplish was to support Move and Link operations, I changed my DoDragDrop call to:

DoDragDrop(dragData, DragDropEffects.Move | DragDropEffects.Link);

This did have the desired effect of getting my GiveFeedback event handler method to support DragDropEffects values of Link.

The fact that DragDropEffects.All does not include the value for Link isn't clearly spelled out on the MSDN help page for DragDropEffects. The description for the All member does say "The data is copied, removed from the drag source, and scrolled in the drop target," but you need to be paying pretty close attention to notice that "Link" isn't mentioned, even assuming that you check the help before using the member in the first place! Similarly, the example code given on the help page for DoDragDrop does use DragDropEffects.All | DragDropEffects.Link in its call to DoDragDrop, but the use of the Link member there isn't called out or noted with a comment.

Due to its counter-intuitive nature, I would go so far as to call the omission of the DragDropEffects.Link bit from the DragDropEffects.All value non-standard... if the DragDropEffects enum wasn't a part of the standard .Net Framework library! :-) Perhaps there is a good historical (legacy support) reason for the exclusion, but if so, it isn't at all clear from just looking at the documentation.

3 comments:

  1. This is clearly a bug. If you look at the tool tip for All it says:

    The combination of the System.Windows.DragDropEffects.Copy, System.Windows.Forms.DragDropEffects.Link,
    System.Windows.Forms.DragDropEffects.Move, and system.Windows.Forms.DragDropEffects.Scroll effects.

    ReplyDelete
  2. Is this still a bug in the current C# version (3.5)? If so, it would be good to report it; I didn't do so at the time of this original posting.

    ReplyDelete
  3. This time, it appears MSDN has it clearly stated it All = "Copy, Move and Scoll".

    http://msdn.microsoft.com/en-us/library/system.windows.forms.dragdropeffects.aspx

    ReplyDelete

Non-spammers: Thanks for visiting! Please go ahead and leave a comment; I read them all!

Attention SPAMMERS: I review all comments before they get posted, and I REPORT 100% of spam comments to Google as spam! Why not avoid getting your account banned as quickly -- and save us both a little time -- by skipping this comment form and moving on to the next one on your list? Thanks, and I hope you have a great day!