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

Hi spammers! No need to waste your time here; comments are heavily moderated, so if you like, you can save us both a little time and just move on to the next site. :-)

For everyone else: Thanks for visiting! Your comments are more than welcome!