如果没有其他实例打开表单打开 – 将类型传递给方法

我想简化一些代码。 因此,如果某个表格已经打开,我想制作一个检查function。 现在,我的开始表单上的每个按钮后面都有代码。

private void button_parts_Click(object sender, EventArgs e) { FormCollection fc = Application.OpenForms; foreach (Form frm in fc) { if (frm is frm_parts) { return; } } frm_Teile newForm = new frm_parts(); newForm.Show(); } 

现在我希望有类似的东西:

 private void button_parts_Click(object sender, EventArgs e) { StartNewForm(frm_parts); } private void StartNewForm(Type myForm) { FormCollection fc = Application.OpenForms; foreach (Form frm in fc) { if (frm is myForm) { return; } } myForm newForm = new myForm(); newForm.Show(); } 

但我无法将类型传递给函数编辑:你当然可以,但我不知道如何以及从何处开始。

有没有(另一种)方式来实现我需要的东西?

您可以使用以下任一选项。

使用通用方法:

 private void StartNewForm() where T : Form, new() { FormCollection fc = Application.OpenForms; foreach (Form frm in fc) { if (frm is T) { return; } } var newForm = new T(); newForm.Show(); } 

以下是用法: StartNewForm();

使用Activator.CreateInstance创建表单

 private void StartNewForm(Type myForm) { FormCollection fc = Application.OpenForms; foreach (Form frm in fc) { if (frm.GetType() == myForm) { return; } } var newForm = (Form)Activator.CreateInstance(myForm); newForm.Show(); } 

这是用法: StartNewForm(typeof(Form1));

注意:

  • 非通用版本只是因为您认为不能使用Type 。 但是你应该知道更好的选择是使用通用版本,因为它在编译时执行类型检查,而在非通用版本中你应该执行一些validation,例如你应该检查myForm是否是Form的类型。

  • 我没有更改你的代码,但是例如你可以这样做:

     private void StartNewForm() where T : Form, new() { var f = (Application.OpenForms.OfType().FirstOrDefault() ?? new T()); f.Show(); } 

对先前答案的改进:

  • 您应该实现某种接口并检查表单是否应该或不应该多次打开。 如果需要,您还可以设置更多属性。 IOnlyOnceForm或类似的东西。
  • 考虑为您要控制的所有表单创建基类。 这样,您可以,例如,只需.Show()它们并继续该方法或中止它并弹出该类型的当前打开实例。 MySuperDuperAppFormBase (您可以自由选择更好的名字!)
  • 另请查看Application.OpenForms.OfType而不是forearch。