PRENDETEVELO NEL CULO
PRENDETEVELO NEL CULO

Reputation: 133

Cannot call Close when Closing event is override

In my MainWindow constructor I ovverided the Closing event because I need to call another method that perform some task, like:

    public MainWindow()
    {
        InitializeComponent();

        Closing += (x, y) =>
        {
            y.Cancel = true;
            _discard = true;
            CheckSettings();
        };
    }

    public void CheckSettings(bool x)
    {
       if(x)
         Close(); 
    }

on the Close line I get:

cannot set visibility or call show or showdialog after window has closed

why??

Upvotes: 0

Views: 334

Answers (2)

Rob
Rob

Reputation: 45771

Until you return from your event handler (that's made the call to CheckSettings), the UI framework you're using may not evaluate the content of the EventArgs that you've named as y and set Cancel = true on.

If you're using WPF, for example, the Close method eventually calls down into another method called VerifyNotClosing (via InternalClose) which at the time of writing looks like this:

private void VerifyNotClosing()
{
    if (_isClosing == true)
    {
        throw new InvalidOperationException(SR.Get(SRID.InvalidOperationDuringClosing));
    }

    if (IsSourceWindowNull == false && IsCompositionTargetInvalid == true)
    {
        throw new InvalidOperationException(SR.Get(SRID.InvalidCompositionTarget));
    }
}

The relevant bit there is the first if that checks a member variable called _isClosing and throws an exception if the form is in the process of closing. The InternalClose method reacts to the state of the Cancel property of the EventArgs after the event handlers have been called:

CancelEventArgs e = new CancelEventArgs(false);
try
{
    // The event handler is called here
    OnClosing(e);
}
catch
{
    CloseWindowBeforeShow();
    throw;
}

// The status of the .Cancel on the EventArgs is not checked until here
if (ShouldCloseWindow(e.Cancel))
{
    CloseWindowBeforeShow();
}
else
{
    _isClosing = false;
    // 03/14/2006 -- hamidm
    // WOSB 1560557 Dialog does not close with ESC key after it has been cancelled
    //
    // No need to reset DialogResult to null here since source window is null.  That means
    // that ShowDialog has not been called and thus no need to worry about DialogResult.
}

The code above (from the InternalClose method) is after the call to VerifyNotClosing which is why the subsequent call to Close, before the first one has finished, results in the exception being thrown.

Upvotes: 1

vc 74
vc 74

Reputation: 38179

(as requested in you comment...) You cannot call Close from a Closing event handler.

If the logic determining if the form can be closed is implemented in CheckSettings:

public MainWindow()
{
    InitializeComponent();

    Closing += (sender, args) =>
    {
        args.Cancel = !CheckSettings();
        ...
    };
}

public bool CheckSettings()
{
   // Check and return true if the form can be closed
}

Upvotes: 1

Related Questions