How to avoid multiple instances of windows form in c#
Asked Answered
R

13

9

How to avoid multiple instances of windows form in c# ?? i want only one instance of the form running. Because there are chances of opening the same form from many pages of my application.

Recalescence answered 10/9, 2009 at 6:4 Comment(0)
T
11

implement the Singleton pattern

an example: CodeProject: Simple Singleton Forms (ok, it's in VB.NET, but just to give you a clue)

Tortoni answered 10/9, 2009 at 6:7 Comment(1)
make sure that you overload FormClosing and check the close reason if the reason is user then hide the form and set cancel = trueTurpeth
C
11

Yes, it has singleton pattern,

Code to create a singleton object,

public partial class Form2 : Form
{
 .....
 private static Form2 inst;
 public static Form2  GetForm
 {
   get
    {
     if (inst == null || inst.IsDisposed)
         inst = new Form2();
     return inst;
     }
 }
 ....
}

Invoke/Show this form,

Form2.GetForm.Show();
Cithara answered 10/9, 2009 at 6:17 Comment(0)
K
9

When you display the dialog simply use .ShowDialog(); instead of .Show();

Kilah answered 12/3, 2014 at 4:9 Comment(2)
very elegant :) i likeNicollenicolson
There are still cases in which you can open multiple instances of a form, even when using ShowDialog. For example, from the menu of the main form, and then from the context menu of the notify icon.Mudd
C
4

One solution I applied to my project in order to bring this form again in the foreground is:

    private bool checkWindowOpen(string windowName)
    {
        for (int i = 0; i < Application.OpenForms.Count; i++)
        {
            if (Application.OpenForms[i].Name.Equals(windowName))
            {
                Application.OpenForms[i].BringToFront();
                return false;
            }
        }
        return true;
    }

windowName is essentially the class name of your Windows Form and return value can be used for not creating a new form instance.

Crum answered 28/12, 2014 at 11:32 Comment(1)
nice article. Solved my issueEffectuate
K
0

If your system has the possibility of showing the same type of form for different instance data then you could create a checking system that iterates all existing open forms, looking for a unique instance data identifier and then re-display any found form.

e.g. having a form class 'CustomerDetails' which contains a public property 'CustomerUniqueID':

foreach(Form f in CurrentlyDisplayedForms)
{
    CustomerDetails details = f as CustomerDetails;
    if((details != null) && (details.CustomerUniqueUD == myCustomerID))
    {
        details.BringToFront();
    }
    else
    {
        CustomerDetails newDetail = new CustomerDetails(myCustomerID);
    }
}

We also use the same mechanism to automatically force refreshes of data binding where a customer's data has been edited and saved.

Kodiak answered 10/9, 2009 at 9:59 Comment(0)
T
0

Try this code

Public class MyClass
{
    //Create a variable named 
    public static int count = 0;
    //Then increment count variable in constructor
    MyClass()
    {
        count++;
    }
}

While creating the object for the above class 'MyClass' check the count value greater than 1

class AnotherClass
{
    public void Event()
    {
        if(ClassName.Count <= 1)
        {
            ClassName classname=new ClassName();
        }
    }
}
Transference answered 7/8, 2012 at 10:20 Comment(0)
E
0

Here is my solution in ShowForm() :

    private void ShowForm(Type typeofForm, string sCaption)
    {
        Form fOpen = GetOpenForm(typeofForm);
        Form fNew = fOpen;
        if (fNew == null)
            fNew = (Form)CreateNewInstanceOfType(typeofForm);
        else
            if (fNew.IsDisposed)
                fNew = (Form)CreateNewInstanceOfType(typeofForm);

        if (fOpen == null)
        {
            fNew.Text = sCaption;
            fNew.ControlBox = true;
            fNew.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            fNew.MaximizeBox = false;
            fNew.MinimizeBox = false;
            // for MdiParent
            //if (f1.MdiParent == null)
            //    f1.MdiParent = CProject.mFMain;
            fNew.StartPosition = FormStartPosition.Manual;
            fNew.Left = 0;
            fNew.Top = 0;
            ShowMsg("Ready");
        }
        fNew.Show();
        fNew.Focus();
    }
    private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
    {
        ShowForm(typeof(FAboutBox), "About");
    }

    private Form GetOpenForm(Type typeofForm)
    {
        FormCollection fc = Application.OpenForms;
        foreach (Form f1 in fc)
            if (f1.GetType() == typeofForm)
                return f1;

        return null;
    }
    private object CreateNewInstanceOfType(Type typeofAny)
    {
        return Activator.CreateInstance(typeofAny);
    }

    public void ShowMsg(string sMsg)
    {
        lblStatus.Text = sMsg;
        if (lblStatus.ForeColor != SystemColors.ControlText)
            lblStatus.ForeColor = SystemColors.ControlText;
    }
Estis answered 28/4, 2013 at 13:41 Comment(0)
C
0

check this link :

using System;

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null) 
          {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }

         return instance;
      }
   }
}
Collie answered 3/2, 2015 at 11:24 Comment(0)
L
0

Here's a simple way to do it.

Check if the form is null, or has been disposed. If that's true we create a new instance of the form.

Otherwise we just show the already running form.

    Form form;
    private void btnDesktop_Click(object sender, EventArgs e)
    {
        if (form == null || desktop.IsDisposed)
        {
            form = new Form();
            form.Show();
        }
        else
        {
            form.WindowState = FormWindowState.Normal;
        }
    }
Lalapalooza answered 6/3, 2018 at 16:51 Comment(0)
P
0
 private static MyForm _myForm;
    internal static MyForm form
    {
        get
        {
            if (_myForm == null)
            {
                _myForm = new MyForm();
            }
            return _myForm;
        }
    }
    public MyForm()
    {
        InitializeComponent();
       _myForm = this;
    }
    private void MyForm_FormClosed(object sender, FormClosedEventArgs e)
    {
        _myForm = null;
    }
Pectase answered 20/7, 2021 at 13:15 Comment(0)
B
0

Here is a reusable generic helper method:

public static class Forms
{
    public static void OpenOnce<TForm>()
        where TForm : Form, new()
    {
        if (Application.OpenForms.OfType<TForm>().FirstOrDefault() is { } form) {
            form.BringToFront();
            if (form.IsFormMinimized()) {
                form.WindowState = FormWindowState.Normal;
            }
        } else { 
            form = new TForm();
            form.Show();
        }
    }
}

You can open or bring to front any form with:

Forms.OpenOnce<MyForm>();
Bartle answered 3/11, 2023 at 15:23 Comment(0)
H
-1

Singletons are not object-oriented. They are simply the object version of global variables. What you can do is to make the constructor of the Form class private, so nobody can accidentally create one of these. Then call in reflection, convert the ctor to public and make sure you create one and only one instance of it.

Hydrophilic answered 10/9, 2009 at 8:8 Comment(1)
That's a very bad idea! Take a look at the 'static class' features of C#, or just use the singleton pattern.Selig
A
-2

You can check the existing processes prior to opening the form:

using System.Diagnostics;

bool ApplicationAlreadyStarted()
{
  return Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName).Length == 0;
}

I don't know if the GetProcessesByName method is affected by UAC or other security measures.

Astrict answered 10/9, 2009 at 6:9 Comment(1)
If you read the question it's not about a singleton application, it's about a form within the app that can be opened from many places and only wanting one instance.Selig

© 2022 - 2024 — McMap. All rights reserved.