Click here to Skip to main content
15,790,723 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have an MDI application containing an MdiParent form and few MdiChild forms. The MdiParent has a fixed MenuStrip, a fixed ToolStrip and a fixed StatusStrip. The MdiChild forms have one or more ToolStrips and a StatusStrip along with other controls in them. The ToolStrips and the StatusStrip of the MdiChild are generally hidden and are only shown when the form is opened in the MdiParent. Based on this scenario I have the following objectives:

1) When an MdiChild is opened in the parent, its ToolStrip(s) should be shown along with the fixed Menu and ToolStrip of the parent. Please note, I ‘m not talking about merging the ToolStrip of the child form to that of the parent. It should show the ToolStrip of the child below the fixed ones of the parent. However, the StatusStrip of the child should merge with that of the parent as usual.

2) When an MdiChild is closed, its ToolStrip(s) should be removed from the MdiParent. The StatusStrip should also be unmerged from that of the parent.

3) As multiple Mdi children can be opened, the ToolStrip(s) of the currently active MdiChild should be shown in the MdiParent and those of the child losing focus should be removed as usual. The same rule is applicable for the StatusStrips also.

What I tried to do is, take a ToolStripPanel in the MdiParent and place the fixed Menu and ToolStrip in it. Then, when the MdiChild is opened or gains focus, add its toolstrip(s) into the ToolStripPanel of the parent. Later when the form loses focus or is closed, remove its toolstrip(s) from the ToolStripPanel of the parent.

The handling of the StatusStrips is typically done by the Merge and RevertMerge methods of ToolStripManager class when the child form opens/gains focus and closes/loses focus respectively.

The relevant code example for one of the child forms follows:

Private Sub CustomerList_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
        If Not MdiParent Is Nothing Then
            Dim parent As Home = MdiParent
            Dim lastIndex As Integer = Array.IndexOf(parent.ToolStripPanel1.Rows, parent.ToolStripPanel1.Rows.Last)
            parent.ToolStripPanel1.Join(Me.ToolStrip1, lastIndex + 1)

            Me.ToolStrip1.Visible = True
            ToolStripManager.Merge(Me.StatusStrip1, CType(Me.MdiParent, Home).StatusStrip1)
        End If
    End Sub

Private Sub CustomerList_Deactivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Deactivate
        If Not MdiParent Is Nothing Then
            Dim parent As Home = MdiParent
            Dim lastIndex As Integer = Array.IndexOf(parent.ToolStripPanel1.Rows, parent.ToolStripPanel1.Rows.Last)
            Array.Clear(parent.ToolStripPanel1.Rows, lastIndex, 1)

            ToolStripManager.RevertMerge(CType(Me.MdiParent, Home).StatusStrip1, Me.StatusStrip1)
        End If
    End Sub

But the problem is, every time I try to close an MdiChild an ObjectDisposedException is thrown stating “Cannot access a disposed object. Object name: ‘Icon’”. The problem doesn’t arise while traversing through the various MdiChild forms. It doesn’t arise while closing the whole application also.

Also, I couldn’t find a way to unjoin items from a ToolStripPanel.

Please help in solving this problem. Also mention if there’s some better way to achieve the above three objectives.

Feel free to ask if I couldn’t make myself clear.


1 solution

Here is the idea: who needs MDI, ever? Why torturing yourself and scaring off your users?
Do yourself a great favor: do not use MDI at all. You can do much easier to implement design without it, with much better quality. MDI is highly discouraged even by Microsoft, in fact, Microsoft dropped it out of WPF and will hardly support it. More importantly, you will scare off all your users if you use MDI. Just don't. Please see:[^],
How to Create MDI Parent Window in WPF?[^].

I can explain what to do instead. Please see my past answers:
How to Create MDI Parent Window in WPF? [Solution 2],
Question on using MDI windows in WPF[^],
MDIContainer giving error[^],
How to set child forms maximized, last childform minimized[^].

Share this answer
priyamtheone 4-Nov-13 10:39am    
Seems to be. Gotto keep up with time. The bunch of your links are useful. Will get back to you as soon as I go through them.

Sergey Alexandrovich Kryukov 4-Nov-13 10:56am    
You are welcome.
Will you accept this answer formally then (green "Accept" button)?
priyamtheone 9-Nov-13 9:31am    
Apart from entirely going to WPF, are there any TDI controls that can be used in Winforms? If yes then, please name me some optimal ones. You know, there are some running projects that customers won't agree to convert to WPF.
Sergey Alexandrovich Kryukov 9-Nov-13 19:20pm    
What do you mean by "TDI". If you mean some controls representing different "pages" or "windows", I would advise few:
1) Panel: you can have several panels on one form showing some (say, just one at a time, depending on some selection). I even used to implement the metaphor of "drawer boxes". You can also implement sliding (accordion-style) panels, or something else.
2) TabConrol with Tab Pages. This is the easiest to implement and use, ready-to-use control.
3) There are advanced 3rd-party open-source components to implement the interface like that of Visual Studio
priyamtheone 18-Nov-13 10:06am    
TDI- Tabbed Document Interface.

Your 2nd point narrows my question correctly. Is there any TDI control that I can use with Visual Studio 2008/2010?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900