Search Forum
(57415 Postings)
Search Site/Articles

Archived Articles
712 Articles

C# Books
C# Consultants
What Is C#?
Download Compiler
Code Archive
Archived Articles
Advertise
Contribute
C# Jobs
Beginners Tutorial
C# Contractors
C# Consulting
Links
C# Manual
Contact Us
Legal

GoDiagram for .NET from Northwoods Software www.nwoods.com


              
Printable Version

Dealing With a Single Instance MDI Child Form
By Roger Frost

The article MDI with C# by Irfan Patel is an excellent guide to developing an MDI Application. I turned to this article for a quick introduction to get my development up and running. I must say that Patel's detailed step-by-step directions combined with his useful yet short explanations make this article easy to read, follow and comprehend.

In less than 15 minutes of developing, I was pleased to see a full implementation of an MDI application skeleton which I could easily build on and use to test other UI concepts.

Like any newly created GUI, after compilation the next step is the most obvious, start clicking and sliding controls. If Patel's steps were followed verbatim, the average user will notice a problem very quickly.

After Opening and Closing the single instance form, the next attempt to open this form will raise an error:

Cannot access a disposed object named "frmSChild".
Object name: "frmSChild".
To clarify, I have decided (and I assume) that a single instance form can be opened more than once. "Single instance" simply means that only one form may be open at any given time, and through the course of running the program, may need to be accessed more than once. Whereas "multiple instance" means that as many forms as needed may be open concurently in the MDI Container.

The problem is with the method GetChildInstance() of the single instance form (frmSChild). This method is required to ensure that this form really is a single instance form. However, it only checks to see if the form hasn't been opened before, it does not check to see if it was previously opened then disposed of. By changing:

if (m_SChildform ==null)

to:

if (m_SChildform ==null || m_SChildform.IsDisposed)
We can check for this second scenario. Now, a new frmSChild will be created not only if it hasn't been created before, but aslo if the pervious instance was closed.

It should be noted that this change will not cause the previous frmSChild instance to be re-opened (ie. there is no such thing as Undispose()). The instance being opened will be in the initial state as defined by the frmSChild class and/or other operations. However, the previous instance surendered all of it's resources at disposal to GC, and therefore this process will not continue to consume more and more resources if it is repeated time and time again.

This solution seems to be the most logical way to handle this problem to me under most circumstances I face. On the other hand, what if in some scenario the single instance form is not to be disposed of everytime we remove it from the interface.

A minor change in frmMDIMain will allow the same instance of a single instance form to be "opened" and "closed" throughout execution. The method mnuFileCloseChild_Click() is responsible for closing the child which is currently active. If we change the line:

objfrmSChild.Close();

to:

objfrmSChild.Hide();
// Be sure the 'if' still uses the Close()
// method, the single instance is handled
// in 'else'
the form will remain in memory, yet will not be visible in the MDI container. This means that if both changes I have mentioned here were used, This change has precedence over the previous, because m_SChildform.IsDisposed will evaluate to false unless frmSChild has been disposed of by some other event. Given this, even if this is the perfered solution to our problem, the previously mentioned change will serve as a safety net incase frmSChild does get disposed of by some other means (ie. in the future an operation is added to close frmSChild elsewhere), and in my opinion would be considered good practice to include at any rate.

Now frmSChild can still be accessed progmatically, even when it is not visible to the user, and all elements of the form remain even after it is hidden. Naturally, if the safety net is to be used as well, any information that was assumed safe as a part of frmSChild will be lost on disposal, therefore may prove to be an unsafe net, especially in larger applications, and lead to logic problems.