1

I tried to search for an answer to this but I couldn't find one, the closest I found was: Create an instance of a class from a string but it doesn't really answer my question:

How do I create an instance of a class from a string, e.g. I want to create a WinForms object and add it to MDI.

I have a function that accepts a string, formname (e.g. "Form1"), and checks MDI children for an instance, if it exists it sets focus, if not then it creates an instance and adds it to the children.

The way I currently create a form is with a case statement but I will have to update this every time I add new Forms to the project! Is there a way of adding an instance of a Form class to the MDI children based on the string passed in, e.g. pseudo-code:

call to function: openForm("Form2");

public void openForm(String formname)
{
    if form exists in MDI children
    {
         focus form with name = formname;
    }
    else
    {
        MDIChildren.add(CreateInstanceOfClassNamed(formname));
    }
}
Community
  • 1
  • 1
Percy
  • 2,855
  • 2
  • 33
  • 56
  • Why doesn't Activator.CreateInstance help you? Where does it fall short? Elaborate. =) – J. Steen Oct 23 '12 at 14:25
  • @J.Steen In the example linked to in my first sentence the answer is Activator.CreateInstance as you suggest: BUT they cast to the object type: ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass)); I do not understand this - they seem to already know the Type as they are casting to (ReportClass) so what if the type returned from Type.GetType(reportClass) was (ReportClass2) for example, this then wouldn't work - or perhaps I am not understanding it correctly??? – Percy Oct 23 '12 at 15:18
  • In your case, all you need to know is that it inherits `Form`, and cast to that. MDIChildren should accept that type. – J. Steen Oct 23 '12 at 15:24

3 Answers3

1

try something like this (pseudocode, no clue about MDI stuff)

public void openForm(String formTypeName)
{
    Form FocusForm = null;
    Type formType = Type.GetType(formTypeName);
    foreach (var form in MDIChildren) 
    {
        if (form.GetType() == formType)
        {
             focusForm = form;
             break;
        }
    }
    if (focusForm == null)
    {
        MDIChildren.add(Activator.CreateInstance(formType));
    }
    // set focus to focusForm
}
Botz3000
  • 39,020
  • 8
  • 103
  • 127
  • This looks more like it - the other example I found had a direct cast to a hardcoded type which for me seemed to defeat the object but this looks more like the thing I need. I will try it and get back to you. – Percy Oct 23 '12 at 15:25
0

Activator can create object from class name:

  object obj = Activator.CreateInstance(Type.GetType(assemblyname + "." +formname));

  ((Form)obj).ShowDialog();
Mohsen Afshin
  • 13,273
  • 10
  • 65
  • 90
0

Rather than passing a string you can just make the function generic:

public TForm GetForm<TForm>()
  where TForm : Form, new()
{
  TForm existingChild = MDIChildren.OfType<TForm>().FirstOrDefult();
  if(existingChild != null)
  {
    //focus, or do whatever
    return existingChild;
  }
  else
  {
    TForm newChild = new TForm();
    //do stuff with new child
    return newChild; 
  }
}

This will ensure that you don't pass the string value of a class that isn't a Form, or isn't of any type at all. You could call it like:

Form2 newChild = GetForm<Form2>();
Servy
  • 202,030
  • 26
  • 332
  • 449
  • Hi, Thanks for the reply - I like the idea as, like you say you cannot pass in a string value that doesn't exist as a class - I am using some 3rd party form controls which currently hold the name of a class, so when I click on them they call my function and pass it the name they hold so I am not sure if I can use your solution - but I will try to as I love using generics - I will let you know! - thanks again. – Percy Oct 23 '12 at 15:27