0

I have a winforms app with many forms. To navigate them, I want to use kind of code:

First form has this to open new window:

    private void Button2_Click(object sender, EventArgs e)
        {
            this.Hide();
            Form2 form2 = new Form2();
            form2.ShowDialog();
            this.Show();
        }

In the second form I have this to go back to previous window:

    private void ButtonReturn_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
        }

But I also have the function to handle closing the second form:

        private void Form2_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult result = MessageBox.Show("Sure?", "Close", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
            if (result.Equals(DialogResult.OK))
            {
                Environment.Exit(0);
            }
            else
            {
                e.Cancel = true;
            }
        }

So my question is the following: I want to use the ButtonReturn to return to previous form without triggering the form closing function, which is set to run on "FormClosing". I want it run only after pressing the red [X] in the window. The buttonReturn should navigate back to previous form without the Dialog Message showing up. How can I achieve this? Because now the closing dialog shows also after clicking on buttonReturn.

TK-421
  • 294
  • 1
  • 7
  • 26
  • Could you `Hide` it somehow? https://stackoverflow.com/questions/2429030/how-to-hide-a-modal-dialog-without-returning-from-showdialog may also be worth a read. – mjwills Jul 22 '19 at 08:08
  • if `this.DialogResult` is not `Ok` then execute the code in `FormClosing` else return. – Matthiee Jul 22 '19 at 08:12
  • @mjwills but if I hide the second form, then I would need to have a lot more code to show the form1 again and that is why I want to use Dialog to avoid the complexity. – TK-421 Jul 22 '19 at 08:16
  • @Matthiee but the "Sure?" is a dialog in FormClosing function, which is in a separate class, so how would I access the DialogResult of Form2 inside FormClosing function? – TK-421 Jul 22 '19 at 08:20
  • Add `bool ClosingByReturnButton = true` in `ButtonReturn_Click` and check the bool value before anything else in `Form_Closing`. If it's `true`, just return. You're not handling for the dialog result in `Button2_Click`, though. – Jimi Jul 22 '19 at 08:21
  • @Jimi I have modified the FormClosing function to accept a third parameter "bool dialog" and now the default vale is true in the form and I change it to false only in ButtonReturn_Click and everything works exactly as I wanted it to. If you woould post this as an answer, I will accept it. – TK-421 Jul 22 '19 at 08:31
  • https://stackoverflow.com/questions/2340566/creating-wizards-for-windows-forms-in-c-sharp – Hans Passant Jul 22 '19 at 11:04
  • @HansPassant what does this have to do with my question? – TK-421 Jul 22 '19 at 11:49
  • Just a very simple way to accomplish the same thing, without the very ugly behavior of having more than one top-level window. Modern apps only have a single main window and modify its content. – Hans Passant Jul 22 '19 at 12:05

2 Answers2

1

You can use the FormClosingEventArgs.CloseReason Property to determine whether or not to show the MessageBox.

Setting the DialogResult property of a modal form is the only time that I know of when the CloseReason will be CloseReason.None. Calling Form.Close or clicking the "X" button will have a CloseReason of CloseReason.UserClosing.

I recommend that you only display the message under the CloseReason.UserClosing condition. This matches your stated intent and also prevents the message from being show for the other possible CloseReason's.

if (e.CloseReason == CloseReason.UserClosing)
{
    DialogResult result = MessageBox.Show("Sure?", "Close", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
    if (result.Equals(DialogResult.OK))
    {
        Environment.Exit(0);
    }
    else
    {
        e.Cancel = true;
    }
}
TnTinMn
  • 11,522
  • 3
  • 18
  • 39
0

The simplest way to do this is to use this.Hide(); within the second form to hide it:

   private void ButtonReturn_Click(object sender, EventArgs e)
    {
        this.Hide();
    }

But the Button2_Click event in your first Form will cause to instatiate a new Form2 everytime you click it. If you want the second form to stay the same / keep values in textboxes and so on you should define your form outside of the button click event and instantiate it only if it was not used yet. Something like this:

     Form2 form2;

    private void Button2_Click(object sender, EventArgs e)
    {
        if(form2 == null) { form2 = new Form2();}
        this.Hide();
        form2.ShowDialog();
        this.Show();
    }

EDIT: To keep the closing event from getting triggered you can just define a boolean to check if the return button was pressed. Then reset the value everytime you open the Form again by using Form_Activated:

    bool showClosingEventMessage = true;
    private void button1_Click(object sender, EventArgs e)
    {
        showClosingEventMessage = false;
        this.Hide();
    }

    private void Form2_Activated(object sender, EventArgs e)
    {
        showClosingEventMessage = true;
    }

    private void Form2_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (showClosingEventMessage)
        {
            DialogResult result = MessageBox.Show("Sure?", "Close", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
            if (result.Equals(DialogResult.OK))
            {
                Environment.Exit(0);
            }
            else
            {
                e.Cancel = true;
            }
        }
    }
colosso
  • 2,525
  • 3
  • 25
  • 49
  • But will widing the form2 send an OK Dialog back to Form1? Won't it just hide the form and I will be stuck with both form1 and form2 hidden? – TK-421 Jul 22 '19 at 08:35
  • Have a look at my edits above. And no, even if you use e.Hide(); in the second Form the this.Show(); in the first form will be triggered. – colosso Jul 22 '19 at 08:48
  • Your edit is almost the same thing which @Jimi suggested in a comment to my question and I have already implemented it. The only difference from your edit is just that instead of hiding the form, I am setting the DialogResult.OK – TK-421 Jul 22 '19 at 09:00
  • And because of that I don't have to check if form2 is null – TK-421 Jul 22 '19 at 09:58
  • I know, but you still gonna instantiate a new Form everytime you perss the button... – colosso Jul 22 '19 at 10:57