lepoco/wpfui · error · InvalidOperationException

DialogHost was not set

Error message

DialogHost was not set

What it means

Thrown by ContentDialog.ShowAsync when both the modern DialogHost and the legacy DialogHostEx backing fields are null. The dialog has nowhere to inject its content, so it refuses to show. This is a configuration precondition failure — the host must be supplied before the async show call.

Source

Thrown at src/Wpf.Ui/Controls/ContentDialog/ContentDialog.cs:718

    private void UpdateIsLegacyHost()
    {
        SetValue(IsLegacyHostPropertyKey, _dialogHostEx is null);
    }

    /// <summary>
    /// Shows the dialog
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage(
        "WpfAnalyzers.DependencyProperty",
        "WPF0041:Set mutable dependency properties using SetCurrentValue",
        Justification = "SetCurrentValue(ContentProperty, ...) will not work"
    )]
    public async Task<ContentDialogResult> ShowAsync(CancellationToken cancellationToken = default)
    {
        if (_dialogHost is null && _dialogHostEx is null)
        {
            throw new InvalidOperationException("DialogHost was not set");
        }

        // Uses `RunContinuationsAsynchronously` to execute continuations asynchronously
        // rather than synchronously on the caller's stack when TCS completes.
        //
        // Benefits:
        // - Prevents UI-thread reentrancy
        // - Eliminates deadlock risks
        // - Ensures predictable continuation scheduling
        Tcs = new TaskCompletionSource<ContentDialogResult>(
            TaskCreationOptions.RunContinuationsAsynchronously
        );

        CancellationTokenRegistration tokenRegistration = cancellationToken.Register(
            o => Tcs.TrySetCanceled((CancellationToken)o!),
            cancellationToken
        );

View on GitHub (pinned to ffebacd610)

Solutions

  1. Set dialog.DialogHost (or DialogHostEx) to a ContentDialogHost instance before calling ShowAsync.
  2. Use FluentWindow which provides a default ContentDialogHost, and show the dialog after the window has loaded.
  3. In XAML, ensure a <ui:ContentDialogHost> exists in the window's content and the dialog is shown from a context where the host is reachable.
  4. Verify the host is non-null in the debugger immediately before the ShowAsync call.

Example fix

// before
var dialog = new ContentDialog { Content = "hi" };
await dialog.ShowAsync(); // throws

// after
var dialog = new ContentDialog { Content = "hi", DialogHost = host };
await dialog.ShowAsync();
Defensive patterns

Strategy: validation

Validate before calling

if (dialog.DialogHost is null && dialog.DialogHostEx is null)
    throw new InvalidOperationException("Configure DialogHost before ShowAsync.");

await dialog.ShowAsync();

Prevention

When it happens

Trigger: Calling await dialog.ShowAsync() on a ContentDialog whose DialogHost (or DialogHostEx) was never set — e.g. the dialog was created in code-behind without a host, or placed in a tree that has no ContentDialogHost ancestor, or the host was nulled out before showing.

Common situations: Building a ContentDialog in code-behind and forgetting to assign DialogHost; using a ContentDialog inside a plain Window (not a FluentWindow with a ContentDialogHost); host set via XAML but the dialog is shown before Loaded so the host resolution has not run.

Related errors


AI-assisted analysis of lepoco/wpfui@ffebacd610 (2026-08-13). Data as JSON: /api/errors/18529a628b3d55aa. Report an issue: GitHub.