dotnet/wpf · error · InvalidOperationException
SR.ShowDialogOnModal
Error message
SR.ShowDialogOnModal
What it means
Only one modal dialog session can run on a Window at a time. If ShowDialog is invoked while the window is already showing as a dialog (_showingAsDialog is true), WPF throws InvalidOperationException(SR.ShowDialogOnModal). This prevents nested/re-entrant modal loops on the same window instance.
Solutions
- Never call ShowDialog on the same window instance while it is modal; show a different (child) window instead
- Guard with a _showingAsDialog-equivalent flag or check window.IsVisible before calling
- Create a fresh Window instance for each modal invocation
- Route repeated requests to the existing dialog and bring it to the foreground instead
Example fix
// before
private void Reopen(object s, RoutedEventArgs e) {
this.ShowDialog(); // re-entrant on same window -> throws
}
// after
private void Reopen(object s, RoutedEventArgs e) {
if (!_showingAsDialog && !IsVisible) {
ShowDialog();
} else {
Activate(); // bring existing dialog forward
}
} Defensive patterns
Strategy: validation
Validate before calling
if (!window.IsVisible && !ReferenceEqualityComparer.Instance.Equals(window, activeWindowShowingDialog)) { window.ShowDialog(); } Type guard
bool CanShowModal(Window w) => !w.IsVisible;
Try / catch
try { window.ShowDialog(); } catch (InvalidOperationException ex) when (ex.Message == SR.ShowDialogOnModal) { window.Activate(); /* already modal */ } Prevention
- Never call ShowDialog from inside the dialog's own handlers
- Use a fresh Window instance for nested modals
- Serialize ShowDialog calls through one entry point
When it happens
Trigger: Calling ShowDialog() again from within the dialog's own event handlers, from code re-entered during the modal message loop, or from multiple threads/commands targeting the same window instance concurrently.
Common situations: A dialog's button handler calling ShowDialog on itself; a command executing ShowDialog re-entrantly while a modal session is active; a shared singleton dialog window opened from two places.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- SR.ShowDialogOnVisible
- Processing is disabled while the Dispatcher is in this…
- SR.ArrangeReentrancyInvalid
- SR.ArrangeReentrancyInvalid
- SR.Automation_RecursivePublicCall
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/b92e37b93d6f9bc8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs:284
/// Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
/// </remarks>
public Nullable<bool> ShowDialog()
{
// this call ends up throwing an exception if ShowDialog
// is not allowed
VerifyApiSupported();
VerifyContextAndObjectState();
VerifyCanShow();
VerifyNotClosing();
VerifyConsistencyWithAllowsTransparency();
if (_isVisible)
{
throw new InvalidOperationException(SR.ShowDialogOnVisible);
}
else if (_showingAsDialog)
{
throw new InvalidOperationException(SR.ShowDialogOnModal);
}
_dialogOwnerHandle = _ownerHandle;
// verify owner handle is window
if (!UnsafeNativeMethods.IsWindow( new HandleRef( null, _dialogOwnerHandle ) ))
{
_dialogOwnerHandle = IntPtr.Zero;
}
// remember the current active window;
// this is used when dialog creation fails or dialog closes, we set the active window back to this one.
_dialogPreviousActiveHandle = UnsafeNativeMethods.GetActiveWindow();
// if owner window is not specified, we get the current active window on this thread's
// message queue as the owner.
if (_dialogOwnerHandle == IntPtr.Zero)View on GitHub (pinned to 81131a70a4)