How to avoid duplicate forms in .NET Windows Forms?

I am using .NET Windows Forms. My parent MDI form contains a menu. If you click on the menu, a form will be displayed. There is still no problem.

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

If I click on the menu again, another duplicate of the form will be created. How to solve this problem?

+4
source share
8 answers

The cleanest way is to simply track the lifetime of the form instance. Do this by signing up for the FormClosed event. For instance:

  private UserForm userFormInstance; private void showUserForm_Click(object sender, EventArgs e) { if (userFormInstance != null) { userFormInstance.WindowState = FormWindowState.Normal; userFormInstance.Focus(); } else { userFormInstance = new UserForm(); userFormInstance.MdiParent = this; userFormInstance.FormClosed += (o, ea) => userFormInstance = null; userFormInstance.Show(); } } 
+5
source

You must create a singleton class to manage 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 template. To use the template correctly, use the link .

Then you can simply access the form as follows:

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

When FormProvider.UserForm opened for the first time, it will be created. Any subsequent hit in the FormProvider.UserForm property returns a form created upon first access. This means that the form will be created only once.

+4
source

Unlike existing answers here, I would not recommend using Singleton for this. The Singleton pattern is terribly confusing, and it’s usually a “code smell” that indicates that something went wrong with your overall design. Singletones are usually placed in the same bucket as global variables: you have a really strong argument for using it.

The easiest solution is to make an instance variable in your main form that represents the form in question, and then use it to display 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
source

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(); 
+3
source

You can always make a Singleton form:

 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 will look something like this:

 MyForm.Instance.Show(); MyForm.Instance.MdiParent = this; 
0
source

Parameters:

Generally, disabling the button works fine and makes more sense from the user's point of view. Singleton works if you need a button for something else.

Singleton is probably not a good solution if the form can be closed and a new instance is needed later.

0
source

You can simply 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 if it does not already exist, and it will switch to the created instance if it exists.

0
source

This is my solution in ShowForm () and calling the sample in aboutToolStripMenuItem_Click ():

  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; } public void ShowError(string sMsg) { lblStatus.Text = sMsg; if (lblStatus.ForeColor != Color.Red) lblStatus.ForeColor = Color.Red; } 
0
source

Source: https://habr.com/ru/post/1312556/


All Articles