views:

2069

answers:

3

I have an MDI application that allows me to open different types of child windows. I can open multiple (but different) instances of the same type of child window. (Example: I can open 3 instances of child window type A and 2 instances of child window type B. All 5 windows are distinct entities and do not share data until unless the user explicitly drags the same data onto multiple windows.) Each child window has a ToolStripContainer with one or more ToolStrips. How do I prevent:

  1. the user from dragging a ToolStrip from a child window of type A to a ToolStripContainer in a child window of type B?
  2. the user from dragging a ToolStrip from one instance of child window A to a ToolStripContainer in another instances of the same type of window?

I'm trying to prevent the user from dragging a ToolStrip from instance 1 of type A to instance 2 of type A, selecting some stuff on instance 2, and then clicking a button on the toolbar only to have something weird happen to some other window. Similarly it doesn't make sense to drag a ToolStrip from a window of type A to a window of type B -- the actions don't apply to that type, but to the user it looks like everything is fine because I let them do the drag.

Is it as simple as adding my own handler for the ControlAdded event or is there a better way to do this? I'm using WinForms in .NET 3.0.

edit: Steps to reproduce

  1. Create a new Windows Application project.
  2. Add a new user control. Give the control a ToolStripContainer that contains one ToolStrip with a single button.
  3. Repeat step 2, giving you a UserControl2 class.
  4. Compile the solution so UserControl1 and UserControl2 show up in your toolbox.
  5. Drag UserControl1 and UserControl2 onto the form. Set the borders so you know where the boundaries are.
  6. Run the app.
  7. It's now possible to drag the ToolStrip from the container in UserControl1 and drop it into the container in UserControl2 (leaving zero ToolStrips in UC1 and two ToolStrips in UC2.)
  8. Now imagine you only have access to the code in UserControl1. How do you prevent the user from dragging the ToolStrip out of that instance of the ToolStripContainer?
A: 

Have you tried to use the DragEnter and DragLeave Events of the ToolStripContainer to identify a ToolStrip dragged over the container an accept or deny it?

Hinek
That only works if you own and have access to all of the ToolStripContainers. See the A/B example above.
Mike Post
I tried to reproduce your problem, but the ToolStrips do not allow to drag them from one instance to another (even of the same type). So what you request should be the default behaviour ...
Hinek
I can reproduce it (following your steps)
Pondidum
+1  A: 

This feels like a hack, but it works (kind of) (sorry, vb.net not c#):

Public Class UserControl2

    Private Sub tsMainMenu_BeginDrag(ByVal sender As Object, ByVal e As System.EventArgs) Handles tsMainMenu.BeginDrag

        tsMainMenu.Tag = tsMainMenu.Parent

    End Sub

    Private Sub ToolStrip1_EndDrag(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsMainMenu.EndDrag


        If Not tsMainMenu.Parent.Parent.Equals(CType(tsMainMenu.Tag, ToolStripPanel).Parent) Then

            CType(ToolStrip1.Tag, ToolStripPanel).Controls.Add(tsMainMenu)
        End If

    End Sub

End Class

simply put; when the control is finished being dragged, if its parent ToolStripContainer is not the same as it was when it started dragging, move the toolstrip back to where it was.

im sure this could be rolled into a control so that you dont have to write it for every toolbar.

Edit: You could put all this code into a control that inherits from ToolStripContainer, and have it do all the work for you, meaning a nice encapsulated solution.

Pondidum
That only works if you have access to all of the code for the toolstrips. See step 8 of my repro steps in the submittal. (Actually I'm not sure that even works: it looks like you're attaching an event handler to the ToolStrip.EndDrag event. The built in handler will still run and perform the drop operation. Easy enough to fix if you own all the toolbar source code, but I don't.)
Mike Post