Search code examples
.netwinformsdelphi-prismoxygeneformclosing

How to prevent Closing and Disposing of a winform in the FormClosing event?


This question may seem like a duplicate, but I just ran in to this issue while I was testing my program and I am kind of confused as to how you solve it.

I have a winform and it has a form closing event. In the event, I pop open a messagebox asking the user, "Are you sure you want to close the window?." If they pushed yes button, the application closes window and prevents it from being disposed as expected. So, I can open it again. However, if they pushed no button, it still closes the window, but now the window is disposed. So, when I try to open it again, it raised an exception, "Cannot access a disposed Object." When No button is pushed, I want the winform remain opened and not disposed.

Here is my code:

method PPMain.PPMain_FormClosing(sender: System.Object; e: System.Windows.Forms.FormClosingEventArgs);
begin
       if MessageBox.Show('Are you sure you want to close the window?','PPMain',MessageBoxButtons.YesNo) = DialogResult.Yes then
       begin
             e.Cancel := true; 
             Hide; 
       end
       else
             e.Cancel := false;
end;

I thought since you have to set e.Cancel = true to close the window and tell it to hide, doing the opposite of that (e.Cancel=false and no hiding) will prevent the winform from closing and being disposed.

How do you solve this?

Thank in advance,


Solution

  • e.Cancel = true prevents the window from closing - it stops the close event.

    e.Cancel = false allows the "close event" to continue (resulting in the window closing and being disposed; assuming nothing else stops it).

    It seems you want to do this:

    method PPMain.PPMain_FormClosing(sender: System.Object; e: System.Windows.Forms.FormClosingEventArgs);
    begin
          e.Cancel := true; 
          if MessageBox.Show('Are you sure you want to close the window?','PPMain',MessageBoxButtons.YesNo) = DialogResult.Yes then
          begin
                Hide; 
          end
    end
    

    e.Cancel := true; prevents the window from closing. The user is then prompted, if they say yes Hide; hides the window (without disposing). If the user clicks No, nothing happens.

    It might be a good idea to detect what kind of close action is being performed. Using e.CloseReason so as not to prevent closing during OS shutdown or something along those lines.

    Like this:

    method PPMain.PPMain_FormClosing(sender: System.Object; e: System.Windows.Forms.FormClosingEventArgs);
    begin
          if e.CloseReason = System.Windows.Forms.CloseReason.UserClosing then
          begin
               e.Cancel := true; 
               if MessageBox.Show('Are you sure you want to close the window?','PPMain',MessageBoxButtons.YesNo) = DialogResult.Yes then
               begin
                     Hide;
               end
          end
    end