tui-cs/Terminal.Gui · error · InvalidOperationException

The Viewport of an AdornmentView cannot be modified.

Error message

The Viewport of an AdornmentView cannot be modified.

What it means

This error is thrown by AdornmentView.Viewport setter because AdornmentView derives its viewport from its parent's adornment (Border, Margin, Padding) thickness and cannot have its viewport set independently. AdornmentViews are internal infrastructure views that represent the visual area of adornments around a parent view. Allowing direct viewport modification would break the geometric relationship between the adornment and its parent.

Source

Thrown at Terminal.Gui/ViewBase/Adornment/AdornmentView.cs:92

        scheme = _scheme ?? Adornment?.Parent?.GetScheme () ?? SchemeManager.GetScheme (Schemes.Base);

        return true;
    }

    /// <inheritdoc/>
    protected override bool OnSettingScheme (ValueChangingEventArgs<Scheme?> args)
    {
        Adornment?.Parent?.SetNeedsDraw ();
        _scheme = args.NewValue;

        return false;
    }

    /// <inheritdoc/>
    public override Rectangle Viewport
    {
        get => base.Viewport;
        set => throw new InvalidOperationException (@"The Viewport of an AdornmentView cannot be modified.");
    }

    /// <inheritdoc/>
    public override Rectangle FrameToScreen ()
    {
        if (Adornment?.Parent is null)
        {
            // Support AllViewsTester where AdornmentView may be a SubView.
            if (SuperView is null)
            {
                return Frame;
            }

            Point super = SuperView.ViewportToScreen (Frame.Location);

            return new Rectangle (super, Frame.Size);
        }

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Do not set Viewport on AdornmentView instances -- their viewport is computed from the parent's adornment thickness.
  2. If writing generic view-processing code, check for AdornmentView and skip the Viewport setter.
  3. To change the effective area, modify the parent's adornment Thickness instead.
  4. If this occurs during deserialization, add a [JsonIgnore] or equivalent to exclude Viewport from serialization on AdornmentView.

Example fix

// before -- setting Viewport on an AdornmentView throws
borderView.Viewport = new Rectangle(0, 0, 10, 5);

// after -- modify the parent's border thickness instead
view.Border.Thickness = new Thickness(1);
Defensive patterns

Strategy: type-guard

Validate before calling

// Before setting Viewport, check if the view is an AdornmentView
if (view is not AdornmentView) { view.Viewport = new Rectangle(0, 0, w, h); }

Type guard

bool IsNotAdornmentView(View v) => v is not AdornmentView;

Try / catch

try { view.Viewport = rect; }
catch (InvalidOperationException ex) when (ex.Message.Contains("AdornmentView"))
{ /* skip; AdornmentView viewport is computed from parent */ }

Prevention

When it happens

Trigger: Thrown at AdornmentView.cs:92 when any code attempts to set the Viewport property on an AdornmentView instance. This could be via direct assignment (view.Viewport = new Rectangle(...)), layout code, or reflection-based serialization/deserialization that sets all properties.

Common situations: Deserialization frameworks that set all properties including Viewport, test helpers that generically configure views, custom layout code that treats AdornmentViews like regular views, or AllViewsTester-style tooling that iterates and sets properties on all view types.

Related errors


AI-assisted analysis of tui-cs/Terminal.Gui@2e47b11478 (2026-08-13). Data as JSON: /api/errors/5f77bd3028fcc901. Report an issue: GitHub.