Search code examples
c#winformsmdichildmdiparent

Opening multiple instances of a child form in a MDI Form with unique identifiers


In my application I want to be able to open a new instance of a form as a child multiple times while they have a unique identifier.

At the moment I do like this:

private int _consoleWindowCount = 0;

private void tsBtNewConsole_Click(object sender, EventArgs e)
{
    _consoleWindowCount++;
    var consoleForm = new ConsoleForm(_consoleWindowCount) { MdiParent = this };
    consoleForm.FormClosing += delegate { _consoleWindowCount--; };
    consoleForm.Show();

    //This will open a new ConsoleForm with Text: Console #_consoleWindowCount 
    //Like:
    // Console #1
    // Console #2

}

I have 2 problems at the moment:

  1. How is it possible that from MDIForm (mainForm) I can programatically doe stuff like BringToFront or Close or ... by the Text property of child forms currently open in the main form
  2. I should not be a genius to find out this way of unique naming of the child forms is not working. If I open 5 child forms (of same form) they will be numbered like Console #1 to Console #5. But if I close lets say Console #4 and if I open a new form (of same form!) it will be named Console #5 then I will have two forms with same name. if this can be fixed, it will be great for forms being distinguishable by user.

Looking forward to your tips in such a case!


Solution

  • I think the logic is a bit broken with the _consoleWindowCount variable.

    Since you are passing in an ID number in the ConsoleForm constructor, just add a ReadOnly property to that form so you can use the id number:

    Example:

    public class ConsoleForm : Form {
      private int _FormID;
    
      public ConsoleForm(int formID) {
        _FormID = formID;
        this.Text = "Console #" + _FormID.ToString();
      }
    
      public int FormID {
        get { return _FormID; }
      }
    }
    

    Creating new forms would require you to iterate through your children collection and looking for the available id to create:

    private void tsBtNewConsole_Click(object sender, EventArgs e) {
      int nextID = 0;
      bool idOK = false;
    
      while (!idOK) {
        idOK = true;
        nextID++;
        foreach (ConsoleForm f in this.MdiChildren.OfType<ConsoleForm>()) {
          if (f.FormID == nextID)
            idOK = false;
        }
      }
    
      var consoleForm = new ConsoleForm(nextID);
      consoleForm.MdiParent = this;
      consoleForm.Show();
    }
    

    You would use the same iteration to determine which form you want to work on:

    private void ShowChildForm(int formID) {
      foreach (ConsoleForm f in this.MdiChildren.OfType<ConsoleForm>()) {
        if (f.FormID == formID)
          f.BringToFront();
      }
    }