lepoco/wpfui · error · InvalidOperationException
Use {nameof(Close)} with MessageBoxResult instead
Error message
Use {nameof(Close)} with MessageBoxResult instead What it means
MessageBox.Close() (the no-arg Window method) is hidden and hard-throws because closing a WPF UI MessageBox requires passing a MessageBoxResult so the internal TaskCompletionSource resolves with the user's choice. Calling the parameterless Close would shut the window without setting a result, leaving awaiters of ShowDialogAsync hanging — so the library forbids it.
Source
Thrown at src/Wpf.Ui/Controls/MessageBox/MessageBox.cs:297
protected TaskCompletionSource<MessageBoxResult>? Tcs { get; set; }
[Obsolete($"Use {nameof(ShowDialogAsync)} instead")]
public new void Show()
{
throw new InvalidOperationException($"Use {nameof(ShowDialogAsync)} instead");
}
[Obsolete($"Use {nameof(ShowDialogAsync)} instead")]
public new bool? ShowDialog()
{
throw new InvalidOperationException($"Use {nameof(ShowDialogAsync)} instead");
}
[Obsolete($"Use {nameof(Close)} with MessageBoxResult instead")]
public new void Close()
{
throw new InvalidOperationException($"Use {nameof(Close)} with MessageBoxResult instead");
}
/// <summary>
/// Displays a message box
/// </summary>
/// <returns><see cref="MessageBoxResult"/></returns>
/// <exception cref="TaskCanceledException">Thrown if the operation is canceled.</exception>
public async Task<MessageBoxResult> ShowDialogAsync(
bool showAsDialog = true,
CancellationToken cancellationToken = default
)
{
Tcs = new TaskCompletionSource<MessageBoxResult>();
CancellationTokenRegistration tokenRegistration = cancellationToken.Register(
o => Tcs.TrySetCanceled((CancellationToken)o!),
cancellationToken
);
View on GitHub (pinned to ffebacd610)
Solutions
- Call messageBox.Close(MessageBoxResult.Ok) (or the appropriate result) so the TCS resolves.
- In a generic 'close all windows' routine, special-case MessageBox and pass a default result.
- Prefer letting the box's own buttons close it; only close programmatically with an explicit result.
- If you must force-close without a result, cancel the ShowDialogAsync CancellationToken instead.
Example fix
// before
var box = new MessageBox { Content = "hi" };
box.Close(); // throws
// after
var box = new MessageBox { Content = "hi" };
box.Close(MessageBoxResult.Ok); Defensive patterns
Strategy: validation
Validate before calling
// Always pass a result when closing programmatically: box.Close(MessageBoxResult.Ok);
Prevention
- Never call the parameterless Close() on a WPF.UI MessageBox.
- Special-case MessageBox in generic 'close all windows' routines.
- Prefer letting the dialog's buttons close it; cancel via CancellationToken if needed.
When it happens
Trigger: Calling messageBox.Close() (no args) on a WPF.UI MessageBox; auto-close logic that calls Close() on any open Window; a 'close all windows' routine that walks the window list.
Common situations: A 'close everything on logout' helper; user code that closes the box from a non-button handler; migration from classic MessageBox where Close() was used to dismiss; CI/automation that dismisses windows generically.
Related errors
- Use {nameof(ShowDialogAsync)} instead
- Failed to get the current `_desiredWidth`.
- Unable to find the base directory of the application.
- Unable to determine the window source.
- Could not get window handle.
AI-assisted analysis of lepoco/wpfui@ffebacd610 (2026-08-13).
Data as JSON: /api/errors/10bb1982f8f0beb1.
Report an issue: GitHub.