I’m studying MDI Form in windows form and I’m playing with this simple application:

Each ToolStripMeniItem calls a single instance of a particular form, but as you can see (please see my code) my code is repetitive for each ToolStripMeniItem, how can I shorten this?
public static Form IsFormAlreadyOpen(Type FormType)
{
foreach (Form OpenForm in Application.OpenForms)
{
if (OpenForm.GetType() == FormType)
return OpenForm;
}
return null;
}
private void form1ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form1 f1 = null;
if (IsFormAlreadyOpen(typeof(Form1)) == null)
{
f1 = new Form1();
f1.MdiParent = this;
f1.Show();
}
else
{
Form selectedForm = IsFormAlreadyOpen(typeof(Form1));
foreach (Form OpenForm in this.MdiChildren)
{
if (OpenForm == selectedForm)
{
if (selectedForm.WindowState == FormWindowState.Minimized)
{
selectedForm.WindowState = FormWindowState.Normal;
}
selectedForm.Select();
}
}
}
}
private void form2ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form2 f2 = null;
if (IsFormAlreadyOpen(typeof(Form2)) == null)
{
f2 = new Form2();
f2.MdiParent = this;
f2.Show();
}
else
{
Form selectedForm = IsFormAlreadyOpen(typeof(Form2));
foreach (Form OpenForm in this.MdiChildren)
{
if (OpenForm == selectedForm)
{
if (selectedForm.WindowState == FormWindowState.Minimized)
{
selectedForm.WindowState = FormWindowState.Normal;
}
selectedForm.Select();
}
}
}
// and so on... for the other ToolStripMeniItem
}
A generic function is a function that will work with a set of types that will be defined by the caller
so instead of
int doubleIt(int a) { return a*2; }you can say
T doubleIt<T>(T a){ return a*2; }this means you can define one function that can be called like this:
So for your code you create a method that takes the form type you’re creating as a value for T.
However the compiler doesn’t know that T is a form and that you can call new on it, so you must contrain the types that can be passed as T with the where clause saying T must be a form and must a constructor that you can access
You therefore replace the core functionality with a generic function that is specialised to the type of f1 that you need.
so instead of
Form f1 = null;you have a generic type that you pass inT f1 = null;Then call this method from the real event handlers
So you end up with something like:
Extra: If you can use Linq, then something like this.
There are other things you can do to shorten this code, however the use of generics and linq will be the most effective.