Hi there
Am a new student in C# and am using Microsoft Visual C# 2013.
My aim is to
i. open a child form inside its MDIparent form
ii. disable the MDIparent form when the child form is active/opened

it was easier in VB.net with

frmStuDetails.ShowDialog()

I have tried

1.

MyChildForm childForm = new MyChildForm();
childForm.ShowDialog(this);

Result....but the problem is that the child form doesn't open within the MDIparent form/container

2.
under MDIparent call button

frmViewStuList childForm = new frmViewStuList(this);
childForm.Owner = this;
childForm.Show();

under child from Activated

 if (this.Owner != null)
  {
    this.Owner.Enabled = false;
  }

under child form Deactivate

 if (this.Owner != null)
 {
   this.Owner.Enabled = true;
 }

Result.....it makes the child form active but freezes the MDIparent when the child form closes

3.

ChildForm child = new ChildForm();
child.Owner = this;
child.Show();

// In ChildForm_Load:
private void ChildForm_Load(object sender, EventArgs e) 
{
  this.Owner.Enabled = false;
}

private void ChildForm_Closed(object sender, EventArgs e) 
{
  this.Owner.Enabled = true;
} 

Result ....It seems to be the best option but the child form doesn't open within the MDIparent

Please help if you have any other idea
Thanks

Dani AI

Generated

In WinForms there is no such thing as a true “modal MDI child.” ShowDialog only works for a top-level window; once you assign MdiParent, the form is not top-level and ShowDialog will throw or refuse to host inside the MDI client. Keep MDI children inside the parent with Show() and MdiParent, and simulate modality by disabling the parent’s command surface (menus/strips/panels) while the child is open. See the ShowDialog exceptions and MDI guidance in the docs. (learn.microsoft.com)

What suggested is the right direction. A small tweak is to disable only the controls that live on the parent, not the parent form itself. That keeps the message loop healthy and avoids getting stranded if something goes wrong. Example pattern from the MDI parent:

// In the MDI parent
private void OpenPseudoModal()
{
    var child = new FrmViewStuList { MdiParent = this, StartPosition = FormStartPosition.CenterParent };
    ToggleParentUi(enabled: false);                // disable MenuStrip/ToolStrips/etc.
    child.FormClosed += (_, __) => ToggleParentUi(true);
    child.Show();
    this.ActivateMdiChild(child);
}

private void ToggleParentUi(bool enabled)
{
    menuStrip1.Enabled = enabled;
    toolStrip1.Enabled = enabled;
    statusStrip1.Enabled = enabled;
    panelLeft.Enabled = enabled; // add any other parent-only panels as needed
}

Two notes:

  • Do not mix Owner with MdiParent. Owner is for top-level windows; the ShowDialog(owner) overload expects a top-level owner, which an MDI child is not. (learn.microsoft.com)
  • If you truly need modality (keyboard/mouse blocked to everything else), use a normal top-level dialog centered over the parent: dlg.StartPosition = CenterParent; dlg.ShowDialog(this); That is the supported model. (learn.microsoft.com)

This keeps the child inside the MDI container and prevents clicks into the parent until the child closes.

Recommended Answers

All 4 Replies

One option would be to just disable the controls on the MDIParent.

First set the MDIParent property insted of the Owner property.

Second add a static method to enable/disable the controls:

    public static void EnableControls(Form thisForm, bool enable = true)
    {
        if (thisForm.IsMdiContainer)
        {
            foreach (Control c in thisForm.Controls)
            {
                //The MDIChild is in the MdiClient.  This way it stays active.               
                if(c.GetType() != typeof(MdiClient))
                {
                    c.Enabled = enable;
                }
            }
        }
    }

In the MDIParent when you show the child also call this new method:

    MdiChildren[0].Show();
    EnableControls(this, false);

In the MDIChild FormClosed event handler re-enable the MDIParent's controls:

//Class of the MDIContainer
Form1.EnableControls(MdiParent);

Guess the static method will be addedto both the child and the MDI parent form.
Is working as expected.
Thanks alot for your answer

Because it's static it just needs to be public in one class. Access it through the class name.

If this works for you please remember to mark this solved. Thanks

Good job
thanks

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.