How to control the form that opened another form from this last in C#?

68 views Asked by At

I'm writing a code where when the user clicks a button, a child form pops up and the user types in information. When the child form comes up, the parent is minimized. I want the parent form to come back up when the user clicks the x button. I'm trying to set the FormWindowState property back to normal in the childform_FormClosed event, but the child form closes while the parent continues to be minimized. I'm using VS community 2019; I saw someone that was able to access the form closing event property through the properties window in the design tab, but I can't find where that is in my version of VS, so I wrote this code in. I've tried the following:

In child form:

private void ChildForm_FormClosed(object sender, FormClosingEventArgs e)
{
    ParentForm frm = (ParentForm)Application.OpenForms["ParentForm"];// find open form
    frm.WindowState = FormWindowState.Normal;
}
2

There are 2 answers

2
Jeroen van Langen On BEST ANSWER

You could register the Closed event within the parent. Those are also available 'outside' the form it self.

For example: (pseudo code)

public partial class FormParent : Form
{
    private FormChild _formChild;

    public void ButtonOpen_Click(object sender, EventArgs e)
    {
        // if the formChild already exists, don't create a new one.
        if(_formChild != null)
        {
            _formChild.BringToFront();
            return;
        }

        _formChild = new FormChild();
        _formChild.Closed += FormChildClosed;
        _formChild.Show();
        this.WindowState = FormWindowState.Minimized;
    }
 
    public void FormChildClosed(object sender, EventArgs e)
    {
        // don't forget to deregister the event, so the old FormChild can be garbage collected.
        _formChild.Closed -= FormChildClosed;
        _formChild = null;
        this.WindowState = FormWindowState.Normal;
    }
}

public partial class FormChild : Form
{
    public FormChild()
    {
        // do something
    }
}

This is what you asked,


This is what I advise, using the ShowModal, which blocks the current method execution. So after the method, you can continue doing what you want to do.

public partial class FormParent : Form
{
    private FormChild _formChild;

    public void ButtonOpen_Click(object sender, EventArgs e)
    {
        _formChild = new FormChild();
        this.WindowState = FormWindowState.Minimized;
        _formChild.ShowModal();
        this.WindowState = FormWindowState.Normal;
    }
}

public partial class FormChild : Form
{
    public FormChild()
    {
        // do something
    }
}
2
AudioBubble On

To have a clean design you should use a form creator pattern and pass the source form like:

ParentForm.cs

WindowState = FormWindowState.Minimized;
ChildForm.Create(this).ShowDialog();

ChildForm.cs

static public ChildForm Create(Form sender)
{
  ChildForm form = new ChildForm();
  form.Sender = sender;
  return form;
}

private Form Sender;

private void ChildForm_FormClosed(object sender, FormClosingEventArgs e)
{
    if (Sender != null)
      Sender.WindowState = FormWindowState.Normal;
}

You can also encapsulate more if you want:

ParentForm.cs

ChildForm.Run(this);

ChildForm.cs

static public void Run(Form sender, bool isDialog)
{
  if (sender != null)
    sender.WindowState = FormWindowState.Minimized;
  ChildForm form = new ChildForm();
  form.Sender = sender;
  if ( isDialog )
    form.ShowDialog();
  else
    form.Show();
}

private Form Sender;

private void ChildForm_FormClosed(object sender, FormClosingEventArgs e)
{
    if (Sender != null)
      Sender.WindowState = FormWindowState.Normal;
}