Click here to Skip to main content
15,883,731 members
Articles / Programming Languages / C#
Article

Singleton pattern for MDI child forms

Rate me:
Please Sign up or sign in to vote.
4.33/5 (27 votes)
22 Jun 20042 min read 119.5K   1.3K   51   18
Use singleton pattern for creating MDI child forms.

Introduction

When you make a MDI (Multi Document Interface) application, you usually need to have only one instance of each child-form to be open at any point of time. You can loop through all the open forms before showing a new form, and make sure that the form has not been opened before. In this article, I show you how you can use singleton pattern to accomplish the same result.

Using the code

The following steps will show you how to make a MDI child form using Singleton pattern.

  1. Make MDI.cs, Form1.cs, and Form2.cs forms. (Set MDI.cs as MDI container.)
  2. Add a menu bar and make two menu items: menuItem1, menuItem2.

If you open form1.cs in code view mode, you should see:

C#
public Form1()
{
    //
    // Required for Windows Form Designer support
    //
    InitializeComponent();

    //
    // TODO: Add any constructor code after InitializeComponent call
    //
}

Since the constructor is public, you can make an instance of Form1 by using "new" keyword:

C#
Form f = new Form1();

Every time you do this, it makes a new instance of Form1. Now, we should implement a logic that makes only one instance and returns that instance wherever Form1 is called.

To do so, make these changes:

C#
private static Form1 aForm= null;
public static Form1  Instance()
{
    if(aForm==null)
    {
        aForm= new Form1();
    }
    return aForm;
}

private Form1()
{
    //
    // Required for Windows Form Designer support
    //
    InitializeComponent();

    //
    // TODO: Add any constructor code after InitializeComponent call
    //
}

Now, every time you need to access an instance of Form1, simply call its Instance() method, which is a public static member:

C#
Form f = Form1.Instance();

First time you call this method, it checks the value of aForm variable, if it is null, it makes an instance of Form1 and assigns it to aForm, which is a static variable. After that, any time you call the Instance() method, it gets the object from the aForm instead of creating a new instance.

Now, let's map menuItem1 to Form1 and menuItem2 to Form2. Double click on menu items, then put the logic in:

C#
private void menuItem1_Click(object sender, System.EventArgs e)
{
    Form f = Form1.Instance();
    f.MdiParent = this;
    f.Show();
    f.Activate();
}

private void menuItem2_Click(object sender, System.EventArgs e)
{
    Form f = new Form2();
    f.MdiParent = this;
    f.Show();
}

There is one more important thing that you need to do. Since aForm is a static variable, if you close the Form1, the value of aForm won't get reset automatically, so you need to do a clean up. To do this, add "aForm = null;" to the dispose method of Form1:

C#
protected override void Dispose( bool disposing )
{
    if( disposing )
    {
        if(components != null)
        {
            components.Dispose();
        }
    }
    base.Dispose( disposing );
    aForm = null;
}

Now, you can run the application. Every time you click on menuItem2, it opens a new instance of Form2, but you can only open one instance of Form1.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Architect
Canada Canada
I worked for the software industry as a software architect, system analyst, senior software engineer and MIS (management information system) consultant for last 10 years.

Comments and Discussions

 
QuestionDisposing Modified Pin
MichlosBSB15-May-21 19:16
MichlosBSB15-May-21 19:16 
C#
protected override void Dispose( bool disposing )
{
    if( disposing )
    {
        if(components != null)
        {
            components.Dispose();
        }
    }
    base.Dispose( disposing );
    aForm = null;
}


Hi guys,
I tried to use this Override. But I didn't get it.
So, I used the event call FormClosing and I get it.


See Cool | :cool: :
C#
private void Form_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (Disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            this.MainView.SetUnselectedButtons(); //this is a event button selected in MainForm
            base.Dispose(Disposing);
            aForm = null;
        }

QuestionSuperb Article!!! Pin
PoojaGRD14-Jul-11 0:52
PoojaGRD14-Jul-11 0:52 
GeneralMy vote of 5 Pin
Ehsan Skardu16-Jul-10 3:47
Ehsan Skardu16-Jul-10 3:47 
GeneralExcellent Article Pin
dawsona052616-Oct-08 8:27
dawsona052616-Oct-08 8:27 
GeneralGood stuff Pin
en_bee26-Apr-07 8:15
en_bee26-Apr-07 8:15 
Generali solved my problem in another way Pin
ismailkirkan1-Nov-06 5:38
ismailkirkan1-Nov-06 5:38 
GeneralMdi Child Form Pin
danmagbiro18-Mar-07 23:29
danmagbiro18-Mar-07 23:29 
GeneralRe: i solved my problem in another way Pin
okutbay5-Oct-07 8:35
okutbay5-Oct-07 8:35 
GeneralThis solution is good Pin
Judylizq16-Jul-06 19:02
Judylizq16-Jul-06 19:02 
Generalit not works fine Pin
thor77@linuxmail.org21-Oct-05 4:45
thor77@linuxmail.org21-Oct-05 4:45 
GeneralCongratulations Pin
Milton Miranda Neto26-Jun-05 14:53
Milton Miranda Neto26-Jun-05 14:53 
Generalgreat article !! Pin
avit11-Feb-05 2:49
avit11-Feb-05 2:49 
GeneralChildren Singletons are NOT .Net Singletons... Pin
Enigmativity29-Jun-04 16:22
Enigmativity29-Jun-04 16:22 
GeneralRe: Children Singletons are NOT .Net Singletons... Pin
Ali Zolghadri30-Jun-04 11:30
Ali Zolghadri30-Jun-04 11:30 
GeneralRe: Children Singletons are NOT .Net Singletons... Pin
Enigmativity30-Jun-04 15:08
Enigmativity30-Jun-04 15:08 
General.dispose Pin
rignhom29-Jun-04 4:19
rignhom29-Jun-04 4:19 
GeneralRe: .dispose Pin
Ali Zolghadri29-Jun-04 7:03
Ali Zolghadri29-Jun-04 7:03 
JokeRe: .dispose Pin
Shiny Zhu13-May-06 1:21
Shiny Zhu13-May-06 1:21 

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

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