Search code examples
c#winformsmdimdichild

How allows ShowDialog MDI children on MDI Form parent?


In the MDI Parent Forms (With the property this.IsMdiContainer = true) we don't are allowed to display any children forms with the method ShowDialog(); automatically will throw the following exception:

A first chance exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll

Additional information: Form that is not a top-level form cannot be displayed as a modal dialog box. Remove the form from any parent form before calling showDialog.

Did anyone has figured out a workaround this problem?


Solution

  • An easy and clean solution that I implemented on my projects is using a callback function (Action<T> in C#) that is triggered when the user put the wanted input.

    Example using ShowDialog:

    private void cmdGetList_Click(object sender, EventArgs e)
    {
        string strInput = "";
    
        frmInputBox frmDialog = new frmInputBox("User input:");
    
        if (frmDialog.ShowDialog() == DialogResult.OK)
            strInput = frmDialog.prpResult;
        else
            strInput = null;
    }
    

    ShowDialog The input box it's outside the MDI Main Form.

    Now; the solution using Show:

    private void cmdGetList_Click(object sender, EventArgs e)
    {
        getInput(this, (string strResult) =>
            {
                MessageBox.Show(strResult);
            });
    }
    
    private void getInput(Form frmParent, Action<string> callback)
    {
        // CUSTOM INPUT BOX
        frmInputBox frmDialog = new frmInputBox("User input:");
    
        // EVENT TO DISPOSE THE FORM
        frmDialog.FormClosed += (object closeSender, FormClosedEventArgs closeE) =>
        {
            frmDialog.Dispose();
            frmDialog = null;
        };
    
        frmDialog.MdiParent = frmParent; // Previosuly I set => frmParent.IsMdiContainer = true;
    
        // frmDialog.ShowDialog(); <== WILL RAISE AN ERROR
        // INSTEAD OF:
        frmDialog.MdiParent = frmParent;
    
        frmDialog.FormClosing += (object sender, FormClosingEventArgs e) =>
        {
            if (frmDialog.DialogResult == DialogResult.OK)
                callback(frmDialog.prpResult);
            else
                callback(null);
        };
    
        frmDialog.Show();
    }
    

    The input box (Or any form will display inside the MDI parent form): ShowExample

    The trick is to use a callback function (Action on C#) to manage when the user put an input.

    It's more code lines, but it's worthless to display a clean project. Final result