What the...?

Something bad happened

We're not sure what, but we have a few guesses.

Problem: Object reference not set to an instance of an object.
Ticket: 7819734
Server: Web03
Single Instance Forms - CodeProject Click here to Skip to main content
11,572,251 members (44,650 online)
Click here to Skip to main content

Single Instance Forms

, 9 Sep 2007 CPOL 45K 787 56
Rate this:
Please Sign up or sign in to vote.
Single instance forms in an MDI application

Introduction

Recently in the C# forum, someone asked about how to ensure single instances of certain forms in an MDI application. In my reply, I used generics and an anonymous delegate to create a slightly more versatile solution to his problem. In his response, he requested an explanation of these topics and perhaps to write (this) an article explaining the code.

The Code

So here are the critical pieces of code in the implementation:

private Dictionary<Type, Form> SingleInstanceForms = new Dictionary<Type, Form>();

protected Form ActivateForm<T>() where T : Form, new()
{
    if (!this.SingleInstanceForms.ContainsKey(typeof(T)))
    {
        T newForm = new T();
        // Set up the necessary properties
        newForm.MdiParent = this;
        newForm.FormClosed += new FormClosedEventHandler
            (delegate(object sender, FormClosedEventArgs e)
        {
            this.SingleInstanceForms.Remove(sender.GetType());
        });
        
        this.SingleInstanceForms.Add(typeof(T), newForm);
    }
    Form formToActivate = this.SingleInstanceForms[typeof(T)];
    formToActivate.Show();
    formToActivate.Activate();

    return formToActivate;
}

That is, in fact, all the code that is required to enforce single instances of certain forms.

Using the Code

To activate (and if need be, create) the desired form, you simply use the following code:

this.ActivateForm<FormType>();

Explanation of the Code

Dictionary

The dictionary is central to the code, it stores the instances of the forms already displayed in the MDI parent, the key associated with it is the Type of the form. The dictionary structure automatically provides us with the means to check whether a Form has been opened previously.

There are advantages and disadvantages to using this. One of the advantages has already been mentioned. The disadvantage is that extra code is required to manage the dictionary, however I feel that this is minor when you contemplate that the only other solution would be to loop through all the existing forms and this will take longer depending on how many forms are open. At the cost of a bit of memory, it is a good solution.

ActivateForm

protected Form ActivateForm<T>() where T : Form, new() { }

This method declaration uses generics to restrict the types being passed to the method with the constraints Form, new(), i.e. T must be of type Form and must have a default constructor.

The method starts of by checking to see if the form's type exists in the dictionary. If not, then it creates a new instance of the form, sets up the necessary properties and adds it to the dictionary.

Anonymous Delegate

The lines of code are as follows:

newForm.FormClosed += new FormClosedEventHandler
    (delegate(object sender, FormClosedEventArgs e)
        {
            this.SingleInstanceForms.Remove(sender.GetType());
        });

It could be rewritten as follows:

newForm.FormClosed += new FormClosedEventHandler(this.MdiChild_FormClosed);
private void MdiChild_FormClosed(object sender, EventArgs e)
{
    this.SingleInstanceForms.Remove(sender.GetType());
}

There are plenty of good explanations of anonymous delegates on the Web, so I won't try and explain those. However the reason the delegate was used rather than a separate method is that it makes the ActivateForm method more compact, i.e. in the source code view, rather than the generated IL.

History

  • 9th September, 2007: Initial post

License

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

Share

About the Author

Ed.Poore
Engineer PooreDesign
United Kingdom United Kingdom
Ed is a student who due to a form of cancer (now clear) took a year out before going to Imperial College, London to study Electronic Engineering.

His interests include shooting (clay-pigeon (shotgun), air-rifle and rifle), playing with his three labradors (Sandy, Rosie and Tundra), programming (most experienced in C# and C, although those are not the only ones), walking (has completed Gold Duke of Edinburgh's Award), playing games and reading.

He lives in two places on a 57 acre farm in West Waleswith the rest of the family during the holidays; and Greater London during term time.

Languages and Technologies: C#, C, VB6, VB.NET, XAML, (X)HTML, CSS, XSLT, Assembler (PIC), ASP.NET, WPF, Windows.Forms, ASP, VBScript, JavaScript, Pascal / Delphi, XML

Current Stuff:
1st Year MEng Electronics Engineering (Imperial College, London)

You may also be interested in...

Comments and Discussions

 
GeneralAn extended version Pin
biopsy3-Jun-08 16:42
memberbiopsy3-Jun-08 16:42 
GeneralRe: An extended version Pin
Ed.Poore3-Jun-08 21:33
memberEd.Poore3-Jun-08 21:33 
GeneralMemory leak Pin
Utwig10-May-08 7:28
memberUtwig10-May-08 7:28 
GeneralRe: Memory leak Pin
Ed.Poore10-May-08 8:13
memberEd.Poore10-May-08 8:13 
GeneralRe: Memory leak Pin
Utwig11-May-08 0:29
memberUtwig11-May-08 0:29 
GeneralRe: Memory leak Pin
Ed.Poore11-May-08 1:30
memberEd.Poore11-May-08 1:30 
GeneralRe: Memory leak Pin
Utwig11-May-08 3:13
memberUtwig11-May-08 3:13 
GeneralRe: Memory leak Pin
Ed.Poore11-May-08 6:53
memberEd.Poore11-May-08 6:53 
GeneralRe: Memory leak Pin
Utwig11-May-08 9:36
memberUtwig11-May-08 9:36 
GeneralRe: Memory leak Pin
Ed.Poore11-May-08 9:44
memberEd.Poore11-May-08 9:44 
GeneralRe: Memory leak Pin
Utwig11-May-08 9:53
memberUtwig11-May-08 9:53 
GeneralThread locking Pin
Jens W10-Sep-07 8:21
memberJens W10-Sep-07 8:21 
GeneralRe: Thread locking Pin
Ed.Poore10-Sep-07 8:25
memberEd.Poore10-Sep-07 8:25 
GeneralRe: Thread locking Pin
Jens W10-Sep-07 8:29
memberJens W10-Sep-07 8:29 
GeneralRe: Thread locking Pin
Ed.Poore10-Sep-07 8:46
memberEd.Poore10-Sep-07 8:46 
GeneralRe: Thread locking Pin
Stuart Carnie10-Sep-07 13:38
memberStuart Carnie10-Sep-07 13:38 
GeneralCool Pin
andalmeida10-Sep-07 5:41
memberandalmeida10-Sep-07 5:41 
General5! Pin
martin_hughes10-Sep-07 2:24
membermartin_hughes10-Sep-07 2:24 
GeneralRe: 5! Pin
Ed.Poore10-Sep-07 2:36
memberEd.Poore10-Sep-07 2:36 
GeneralRe: 5! Pin
martin_hughes10-Sep-07 2:37
membermartin_hughes10-Sep-07 2:37 
GeneralAlternate solution Pin
maspr10-Sep-07 1:47
membermaspr10-Sep-07 1:47 
GeneralRe: Alternate solution Pin
Ed.Poore10-Sep-07 2:09
memberEd.Poore10-Sep-07 2:09 
GeneralGot my 5 Pin
Marc Clifton10-Sep-07 1:31
protectorMarc Clifton10-Sep-07 1:31 
GeneralRe: Got my 5 Pin
Ed.Poore10-Sep-07 2:02
memberEd.Poore10-Sep-07 2:02 
GeneralRe: Got my 5 Pin
Colin Angus Mackay10-Sep-07 5:58
mvpColin Angus Mackay10-Sep-07 5:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150624.2 | Last Updated 9 Sep 2007
Article Copyright 2007 by Ed.Poore
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid