Question

I have successfully created DragDrop functionality with user controls. Now I am trying to allow DragDrop functionality on some components such as ToolStripButton.

The base class, ToolStripItem, supports AllowDrop and the DragEnter/DragDrop events...

ToolStripButton hides these properties in the designer, but they are publicly accessable.

Originally I tried doing the following for each ToolStripButton:

button.AllowDrop = true;
button.DragEnter += new DragEventHandler(button_DragEnter);
button.DragDrop += new DragEventHandler(button_DragDrop);

However, the events were not ever firing. These buttons are contained within a MenuStrip, so I changed the MenuStrip.AllowDrop to true. Then I started getting DragEnter and DragDrop events, but the DragDrop event would fail due to a threading/invoke problem when accessing the Tag property of the ToolStripItem.

The ToolStripItems cannot be invoked upon. So I have tried invoking their container, the MenuStrip, with the same function. I am still getting a threading/invoke problem where the thread stops running as soon as I try to access the ToolStripItem.

Here is the code I'm using to retrieve the Tag information after invoke:

void button_DragDrop(object sender, DragEventArgs e)
{
    menuStrip.Invoke(new DragEventHandler(MyDragFunction), new object[] { sender, e });
}

void MyDragFunction(object sender, DragEventArgs e)
{
    int id = (int)((ToolStripButton)sender).Tag;
    // Debugging never reaches this line
    int dragId = (int)e.Data.GetData(DataFormatName, false);

    MoveItem(id, dragId);
}

Is Drag and Drop to a component like a ToolStripItem simply not possible? Or am I doing something wrong?

Was it helpful?

Solution

Here is the code I got to work for me.

I assign the DragDrop properties in the form constructor since they are hidden in the designer.

foreach (object o in menuStrip.Items)
{
    if (o is ToolStripButton)
    {
        ToolStripItem item = (ToolStripItem)o;

        item.AllowDrop = true;
        item.DragEnter += new DragEventHandler(item_DragEnter);
        item.DragOver += new DragEventHandler(item_DragOver);
        item.DragDrop += new DragEventHandler(item_DragDrop);
    }
}

private void item_DragEnter(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormatName, false))
    {
        e.Effect = DragDropEffects.Move;
    }
}

private void item_DragOver(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(DataFormatName, false))
    {
        e.Effect = DragDropEffects.Move;
    }
}

private void item_DragDrop(object sender, DragEventArgs e)
{
    int id = (int)e.Data.GetData(DataFormatName, false);
    int category = Convert.ToInt32((sender as ToolStripButton).Tag);

    MyFunction(category, id);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top