How can I make a single instance form (not application)?

柔情痞子 提交于 2019-11-27 09:04:59

You will need this form as property

Form1 myForm = null;
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    myForm = null;
}

private void ShowForm()
{
    if (myForm != null)
    {
        myForm.BringToFront();
    }
    else
    {
        myForm = new Form1;
        myForm.Show();
    }
}

Well, the simplest way is to have a static field which stores a reference to the single instance or null, and then a method to retrieve it or create a new one.

Note that this isn't the same as making it a singleton - because I assume if the form is closed, you'd want to create a new instance next time. (The alternative - hiding it and reusing it - is shown in STO's answer.) You may want something like this:

public class OptionsDialog : Form
{
    private static OptionsDialog openForm = null;

    // No need for locking - you'll be doing all this on the UI thread...
    public static OptionsDialog GetInstance() 
    {
        if (openForm == null)
        {
            openForm = new OptionsDialog();
            openForm.FormClosed += delegate { openForm = null; };
        }
        return openForm;
    }
}

You may want to make the method perform the "bring it to the front" steps as well, of course.

You need to prevent the form from closing. If you don't, the form will be disposed and becomes unusable. You can do this by implementing the FormClosing event:

    protected override void OnFormClosing(FormClosingEventArgs e) {
        if (e.CloseReason == CloseReason.UserClosing) {
            this.Hide();
            e.Cancel = true;
        }
    }

To make it a singleton, just keep track of the life time of the form in your main form class:

    frmOptions options;

    private void btnShowOptions_Click(object sender, EventArgs e) {
        if (options == null) {
            options = new frmOptions();
            // To make absolutely sure:
            options.FormClosed += (o, ea) => options = null;
        }
        else {
            options.WindowState = FormWindowState.Normal;
        }
        options.Show();
    }

you may use code like this:

private MyDialogForm _FormInstance;

public void ShowOptions()
{
     if (_FormInstance == null)
     {
        _FormInstance = new MyDialogForm();
        _FormInstance.FormClosing += (s,e) => 
        {
             e.Cancel = true;
             _FormInstance.Hide();
        }
      }
     _FormInstance.Show();
}

I assume you have at least two forms. One form, call it frmMain, allows you to open frmOptions. In frmMain, add a variable of type frmOptions like this:

public partial class frmMain : Form
{
     private frmOptions optionsInstance = null;
     ...

In the routine that opens the Options dialog, add this:

if (optionsInstance == null || !optionsInstance.Visible)
{
     optionsInstance = new frmOptions();
     optionsInstance.Show();
}

When frmOptions closes, optionsInstance will not be null, so that's why you check if it's visible before instantiating a frmOptions instance.

If this doesn't work for you, you could try a mutex, but that's probably overkill.

Alex Vang

Based on Jon Skeet's answer, I'm using the following code for showing a form as a modal dialog box.

        if (this.aboutForm == null)
        {
            this.aboutForm = new AboutForm();
            this.aboutForm.FormClosed += (sender2, e2) => { this.aboutForm = null; };
            this.aboutForm.ShowDialog(this);
        }
        else
        {
            this.aboutForm.Focus();
        }

I have to do this because I have a menu item to display the About form in the menu of the main form, and in the context menu of the notify icon. If I open the About form using the menu of the main form, I still can open another instance by using the context menu item of the notify icon.

    Main_Frm _main_Frm = null;

    private void Show_bt_Click(object sender, EventArgs e)
    {

        if (_main_Frm != null)
        {
            _main_Frm .BringToFront();
        }
        else
        {
            _main_Frm = new Comission_Frm();
            _main_Frm .Show();
        }

         //This condition used when you closed the form the form will disposed and when you reopen.
        if (_main_Frm .IsDisposed)
        {
            _main_Frm = new _Main_Frm ();
            _main_Frm .Show();
        }
   }

This May Help! Note: The following code was taken from the article Below: https://www.dotnetcurry.com/ShowArticle.aspx?ID=150

static class Program
    {
        ///<summary>
        /// The main entry point for the application.
        ///</summary>
        [STAThread]
        static void Main()
        {
            bool instanceCountOne = false;

            using (Mutex mtex = new Mutex(true, "MyRunningApp", out instanceCountOne))
            {
                if (instanceCountOne)
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new Form1());
                    mtex.ReleaseMutex();
                }
                else
                {
                    MessageBox.Show("An application instance is already running");
                }
            }
        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!