{"record":{"id":"0badc72ff8014ef2","repo":"MaterialDesignInXAML/MaterialDesignInXamlToolkit","slug":"cannot-cancel-dialog-closing-after-nameof-isopen","errorCode":null,"errorMessage":"Cannot cancel dialog closing after {nameof(IsOpen)} property has been set to {bool.FalseString}","messagePattern":"Cannot cancel dialog closing after (.+?) property has been set to (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/MaterialDesignThemes.Wpf/DialogHost.cs","lineNumber":354,"sourceCode":"                // * the attached property (which should be applied to the button which opened the dialog\n                // * straight forward IsOpen dependency property \n                // * handler provided to the async show method\n                var dialogClosedEventArgs = new DialogClosedEventArgs(dialogHost.CurrentSession, DialogClosedEvent);\n                dialogHost.OnDialogClosed(dialogClosedEventArgs);\n                dialogHost._attachedDialogClosedEventHandler?.Invoke(dialogHost, dialogClosedEventArgs);\n                dialogHost.DialogClosedCallback?.Invoke(dialogHost, dialogClosedEventArgs);\n                dialogHost._asyncShowClosedEventHandler?.Invoke(dialogHost, dialogClosedEventArgs);\n                dialogHost._attachedDialogClosedEventHandler = null;\n\n                if (!session.IsEnded)\n                {\n                    session.Close(session.CloseParameter);\n                }\n                //DialogSession.Close may attempt to cancel the closing of the dialog.\n                //When the dialog is closed in this manner it is not valid\n                if (!session.IsEnded)\n                {\n                    throw new InvalidOperationException($\"Cannot cancel dialog closing after {nameof(IsOpen)} property has been set to {bool.FalseString}\");\n                }\n                closeParameter = session.CloseParameter;\n                dialogHost.CurrentSession = null;\n            }\n\n            //NB: _dialogTaskCompletionSource is only set in the case where the dialog is shown with Show\n            dialogHost._dialogTaskCompletionSource?.TrySetResult(closeParameter);\n\n            // Don't attempt to Invoke if _restoreFocusDialogClose hasn't been assigned yet. Can occur\n            // if the MainWindow has started up minimized. Even when Show() has been called, this doesn't\n            // seem to have been set.\n            dialogHost.Dispatcher.InvokeAsync(() => dialogHost._restoreFocusDialogClose?.Focus(), DispatcherPriority.Input);\n\n            return;\n        }\n\n        dialogHost.CurrentSession = new DialogSession(dialogHost);\n        var window = Window.GetWindow(dialogHost);","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/98edec3a0b96ef272c587b14bcd67ef5f928a7ed/src/MaterialDesignThemes.Wpf/DialogHost.cs#L336-L372","documentation":"Thrown inside the IsOpen property-changed callback after the host has already set IsOpen=false and run the closing sequence. A DialogSession.Close that cancels closing is invalid at that point: the host cannot re-open a dialog whose IsOpen is already false, so a closing handler calling e.Cancel() (which keeps IsEnded false) triggers the guard at DialogHost.cs:354.","triggerScenarios":"A DialogClosingEventHandler calls session.Close(...) or sets IsCancelled during the final closing pass, or programmatic InternalClose is invoked while the property transition is mid-flight and the session tries to cancel. Specifically: session.Close in the closing callback leaves IsEnded false, hitting the check.","commonSituations":"Custom closing handlers that conditionally cancel; view-model logic that calls session.Close inside DialogClosing; re-entrant close attempts after IsOpen was already set to false programmatically or via binding.","solutions":["Do not call DialogSession.Close inside a DialogClosingEventHandler or after IsOpen has been set to false; let the close proceed.","If you must react, only cancel the close BEFORE IsOpen flips (set e.Cancel in the closing handler) and never call session.Close during closing.","Audit any code path that sets IsOpen=false directly via binding/SetCurrentValue and remove custom cancel logic there.","Restructure so cancellation happens in the closing event (DialogClosingEventArgs.Cancel) rather than via session.Close after the fact."],"exampleFix":"// before (throws)\nprivate void Host_DialogClosing(object s, DialogClosingEventArgs e)\n{\n    e.Session.Close(e.Parameter); // session.IsEnded stays false -> throw\n}\n\n// after\nprivate void Host_DialogClosing(object s, DialogClosingEventArgs e)\n{\n    if (mustCancel) e.Cancel(); // legitimate cancellation before IsOpen flips\n}","handlingStrategy":"validation","validationCode":"// In a DialogClosing handler, do not call session.Close; only cancel if needed.\nprivate void Host_DialogClosing(object? s, DialogClosingEventArgs e)\n{\n    if (KeepOpenCondition)\n        e.Cancel(); // valid before IsOpen flips; do NOT call e.Session.Close here\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never call DialogSession.Close inside DialogClosing/DialogClosed handlers.","If you must prevent close, set DialogClosingEventArgs.Cancel before IsOpen flips to false.","Audit any code path that sets IsOpen=false directly and remove cancel-then-close logic."],"tags":["wpf","materialdesigninxaml","dialog","lifecycle","event-handling"],"backgroundTag":null,"analyzedSha":"98edec3a0b96ef272c587b14bcd67ef5f928a7ed","analyzedAt":"2026-08-13T14:31:19.111Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}