How to avoid duplicate form creation in .NET Windo

2020-06-21 07:05发布

I am using .NET Windows Forms. My MDI parent form contains the menu. If click the menu the form will be displayed. Up to now no problem.

UserForm uf = new UserForm();
uf.Show();
uf.MdiParent = this;

If I click the menu again another duplicate of the form is created. How to solve this issue?

8条回答
我欲成王,谁敢阻挡
2楼-- · 2020-06-21 07:42

You could just examine the MdiChildren property of your host form to determine if an instance of your UserForm exists in it.

UserForm myForm = null;
foreach (Form existingForm in this.MdiChildren)
{
    myForm = existingForm as UserForm;
    if (myForm != null)
        break;
}

if (myForm == null)
{
    myForm = new UserForm();
    myForm.MdiParent = this;

    myForm.Show();
}
else
    myForm.Activate();

This will create a new instance of your UserForm is it doesn't already exist, and it will switch to the created instance if it does exist.

查看更多
聊天终结者
3楼-- · 2020-06-21 07:49

In contrast to the existing answers here, I would not recommend using a Singleton for this. The Singleton pattern is woefully overused, and is generally a "code smell" that indicates that something's gone wrong with your overall design. Singletons are generally put in the same "bucket" as global variables: you'd better have a really strong case for using it.

The simplest solution is to make an instance variable on your main form that represents the form in question, then use that to show it.

public class MainMdiForm : Form
{
    ...

    UserForm userForm;

    ...

    private void ShowUserForm()
    {
        if(userForm == null || userForm.IsDisposed)
        {
            userForm = new UserForm();
            userForm.MdiParent = this;
        }

        userForm.Show();
        userForm.BringToFront();
    }
}
查看更多
聊天终结者
4楼-- · 2020-06-21 07:49

Options:

Typically, disabling the button works fine, and makes more sense from the user's perspective. Singleton works if you need the button enabled for something else.

Singleton is probably not a good solution if the form could be closed and a new instance will later be required.

查看更多
神经病院院长
5楼-- · 2020-06-21 07:50

If you know the name of the form :

    if (Application.OpenForms["FormName"] == null)
       {
           Form form = new Form();
           form.MdiParent = this;
           form.Show();
       }
       else
           Application.OpenForms["FormName"].Focus(); 
查看更多
男人必须洒脱
6楼-- · 2020-06-21 07:52

You could always make the Form a Singleton:

public class MyForm : Form
{
    private MyForm _instance = null;
    private object _lock = new object();

    private MyForm() { }


    public static MyForm Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (_lock)
                {
                    if (_instance == null)
                    _instance = new MyForm();
                }
            }
            return _instance;
        }
    }
}

Then your call would look something like:

MyForm.Instance.Show();
MyForm.Instance.MdiParent = this;
查看更多
你好瞎i
7楼-- · 2020-06-21 07:55

You should create a singleton class for managing your form instances:

public class FormProvider
{
   public static UserForm UserForm
   {
       get
       {
          if (_userForm== null || _userForm.IsDisposed)
          {
            _userForm= new UserForm ();
          }
          return _userForm;
       }
   }
   private static UserForm _userForm;
}

NB, this is a very simple Singleton pattern. For the correct way to use the pattern, use this link.

You can then just access the form as follows:

FormProvider.UserForm.Show();
FormProvider.UserForm.MdiParent = this;

When FormProvider.UserForm is accessed for the FIRST time, it will be created. Any subsequent get on the FormProvider.UserForm property will return the form that was created on first access. This means that the form will only ever be created once.

查看更多
登录 后发表回答