Diego Diego - 2 months ago 18
C# Question

Open a Form if there is not another instance of it Open - Pass Type to a Method

I want to simplify some of my code. Therefore i want to make a function wich checks, if a certain form is already open. Right now i have the code below behind every button on my start-form.

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();
}


Now i would like to have something like:

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();
}


But i cannot pass a type to a function
EDIT: You certainly can, but i didn't know how and where to start.

Is there a(nother) way to achive what i need?

Answer

You can use either of these options.

Using a generic method:

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();
}

Here is the usage: StartNewForm<Form1>();

Create your form using 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();
}

Here is the usage: StartNewForm(typeof(Form1));

Note:

  • The non-generic version is here just because you thought you can't do it using Type. But you should know the better option is using generic version because it performs type checking at compile time while in the non-generic version you should perform some validations, for example you should check if myForm is of type of Form.

  • I didn't change your code, but for example you can do it this way:

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