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

Die*_*ego 3 c# forms winforms

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

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();
}
Run Code Online (Sandbox Code Playgroud)

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

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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

Rez*_*aei 6

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

使用通用方法:

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

这是用法: StartNewForm<Form1>();

使用创建表单 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();
}
Run Code Online (Sandbox Code Playgroud)

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

注意:

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

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

    private void StartNewForm<T>() where T : Form, new()
    {
        var f = (Application.OpenForms.OfType<T>().FirstOrDefault() ?? new T());
        f.Show();
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • 是的,*总是*当你可以使用它时更喜欢通用方法.不要推迟运行时在编译时可以验证的内容.您不仅可以提升性能,更重要的是,您可以确保正确性. (2认同)