lepoco/wpfui · error · InvalidOperationException

Cannot set ContentDialogHost: a legacy ContentPresenter…

Error message

Cannot set ContentDialogHost: a legacy ContentPresenter host has already been set. Only one host type is allowed per instance for compatibility.

What it means

Thrown by ContentDialogService.SetDialogHost(ContentDialogHost) when the legacy host (_dialogHost of type ContentPresenter) is already set. This is the symmetric guard to error 11: once a ContentPresenter host is in use, switching to ContentDialogHost on the same instance is rejected to avoid mixed hosting.

Solutions

  1. Standardize on ContentDialogHost for the instance and avoid the legacy ContentPresenter host entirely.
  2. If mid-migration, ensure only one SetDialogHost call runs per service instance; guard with a flag or restructure DI registration.
  3. Use distinct ContentDialogService instances when both host styles must coexist in the app.

Example fix

// before
contentDialogService.SetDialogHost(myContentDialogHost); // _dialogHost already set

// after
// remove the earlier legacy call and use only:
contentDialogService.SetDialogHost(myContentDialogHost);
Defensive patterns

Strategy: validation

Validate before calling

if (_dialogService.GetDialogHost() is null) { _dialogService.SetDialogHost(dialogHost); }

Type guard

static bool LegacyHostUnset(IContentDialogService svc) => svc.GetDialogHost() is null;

Prevention

When it happens

Trigger: Calling SetDialogHost(ContentDialogHost) after the obsolete SetDialogHost(ContentPresenter) was already invoked. The field _dialogHost is non-null, so the InvalidOperationException fires.

Common situations: App initializes with the legacy ContentPresenter host (from older tutorials) and then attempts to upgrade to ContentDialogHost without clearing the prior host, or two different code paths each set a host type.

Related errors


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

Appendix: source

Thrown at src/Wpf.Ui/ContentDialogService.cs:103

    /// <remarks>
    /// <para>
    /// This method sets the enhanced <see cref="ContentDialogHost"/> to contain and manage dialogs.
    /// For compatibility reasons, an instance can have either a legacy host (set via
    /// <see cref="SetDialogHost(ContentPresenter)"/>) or an enhanced host (set via this method),
    /// but not both.
    /// </para>
    /// </remarks>
    public void SetDialogHost(ContentDialogHost dialogHost)
    {
        if (dialogHost == null)
        {
            throw new ArgumentNullException(nameof(dialogHost));
        }

        // Defense mechanism: prevent mixed host types for compatibility
        if (_dialogHost != null)
        {
            throw new InvalidOperationException(
                "Cannot set ContentDialogHost: a legacy ContentPresenter host has already been set. "
                    + "Only one host type is allowed per instance for compatibility."
            );
        }

        _dialogHostEx = dialogHost;
    }

    /// <inheritdoc/>
    public ContentDialogHost? GetDialogHostEx()
    {
        return _dialogHostEx;
    }

    /// <inheritdoc/>
    public Task<ContentDialogResult> ShowAsync(ContentDialog dialog, CancellationToken cancellationToken)
    {
#pragma warning disable CS0618 // (Warning: Obsolete) To maintain compatibility

View on GitHub (pinned to ffebacd610)