4

I am developing a C# Windows Forms application. I would like to have a single instance of all the forms.

So, when the user clicks on the Contact button, for instance, twice, instead of having two contact forms, I would to bring the single instance contact form to the front.

How can I achieve this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kiran
  • 8,034
  • 36
  • 110
  • 176

7 Answers7

9

Check if the form exists in collection of open forms before creating and showing the form using Application.OpenForms

if (System.Windows.Forms.Application.OpenForms["Form1"] as Form1 != null)
       MessageBox.Show("Form1 is opened");
 else
       MessageBox.Show("Form1 is not opened");
Adil
  • 146,340
  • 25
  • 209
  • 204
3
public static Form GetOpenedForm<T>() where T: Form {
    foreach (Form openForm in Application.OpenForms) {
        if (openForm.GetType() == typeof(T)) {
            return openForm;
        }
    }
    return null;
}

And in your code, where you create the ContactForm:

ContactForm form = (ContactForm) GetOpenedForm<ContactForm>();
if (form == null) {
    form = new ContactForm();
    form.Show();
} else {
    form.Select();
}
Otiel
  • 18,404
  • 16
  • 78
  • 126
  • 2
    Make the return value of your static method `T`. In that case you don't need the cast in your usage: `ContactForm form = GetOpenedForm();` – Oliver Oct 19 '12 at 07:31
  • Using LINQ you could make a one liner out of your helper method: `return Application.OpenForms.OfType.FirstOrDefault()` – Oliver Oct 19 '12 at 07:32
  • 1
    This wont work if the form is minimized, so you can add a WindowState Normal. See my answer below – Alejandro del Río Feb 04 '14 at 19:13
2

Simple as that:

Form fc = Application.OpenForms["Form1"];
            if (fc != null)
            {
                fc.Focus();
            }
            else
            {
                Form1 f1 = new Form1();
                f1.Show();
            }
Samy S.Rathore
  • 1,825
  • 3
  • 26
  • 43
2

You can disable the contactButton when it is clicked and open the contactForm-

private void contactButton_Click(object sender, EventArgs e)
{
  contactButton.Enabled=false;
  //code to open the contactForm
}

When the contactForm is closed, you can re-enable the button-

contactButton.Enabled=true;
Sunil Nadar
  • 517
  • 1
  • 5
  • 15
1

Try this combo

First make contact form a global object

private ContactForm contactForm;

Then your contact button handler:

private void contactButton_Click(object sender, EventArgs e)
{
    if (contactForm == null)
    {
       contactForm = new ContactForm();
       contactForm.FormClosing += new FormClosingEventHandler(contactForm_FormClosing);
    }
    contactForm.Show();
}

Then handle the FormClosing event of the ContactForm to hide it rather than close it:

private void contactForm_FormClosing(object sender, FormClosingEventArgs e)
{
    contactForm.Hide();
    e.Cancel = true;
}

Or if you want the contact form to close, and open as new next time, handle the FormClosed instead:

private void contactForm_FormClosed(object sender, FormClosedEventArgs e)
{
    contactForm = null;
}

Then next time the button is clicked, the null if clause will be caught and the form will be set to a new instance and opened.

Wanabrutbeer
  • 676
  • 6
  • 11
1
Form2 form2 = null;
private void button1_Click(object sender, EventArgs e)
{
 bool isFormExists = false;
 foreach (Form openForm in Application.OpenForms)
 {
  if (openForm == form2 && openForm!=null)
  {
   openForm.Focus();
   isFormExists = true;
   break;
  }
 }

 if (!isFormExists)
 {
  form2 = new Form2();
  form2.Show();
 }
}
andy
  • 5,979
  • 2
  • 27
  • 49
1

I'd go with Otiel's answer. Also you can add a WindowState, because if the form is minimized it won't be shown. this answer can be used to get the restore method.

ContactForm form = (ContactForm) GetOpenedForm<ContactForm>();
if (form == null) {
    form = new ContactForm();
    form.Show();
} else {
    //use this (if you want it to be restored to normal and focused)
    //no need of extension method
    //form.WindowState = FormWindowState.Normal;
    //form.Select();

    //or use this if you want it to be restored as previous state and focused
    //You need a Restore extension method that can be found in the link above
    form.Focus();
    form.Restore();
}
Community
  • 1
  • 1
Alejandro del Río
  • 3,966
  • 3
  • 33
  • 31
  • 1
    This won't perfectly work in case of the `WindowState` was maximized (or maximized before being minimzed). You can use the `Restore` method [here](http://stackoverflow.com/a/2725234/825024) instead of modifying the `WindowState` property. – Otiel Feb 05 '14 at 09:58
  • Yeah, in this case it's forced to go normal state. It depends on what you want. Thanks. – Alejandro del Río Feb 05 '14 at 16:26
  • I tested the restore thing. If we use restore, we have to add focus to the form too. Otherwise it stays back. I Edited my answer. – Alejandro del Río Feb 05 '14 at 16:37
  • I kept the `Select` in fact. But I guess this is the same. `form.Restore(); form.Select();` – Otiel Feb 07 '14 at 16:20