Skip to content

Empty Document Host Content + Template Support#1032

Merged
wieslawsoltes merged 4 commits intomasterfrom
feature/empty-content-template-placeholders
Feb 9, 2026
Merged

Empty Document Host Content + Template Support#1032
wieslawsoltes merged 4 commits intomasterfrom
feature/empty-content-template-placeholders

Conversation

@wieslawsoltes
Copy link
Copy Markdown
Owner

PR Summary: Empty Document Host Content + Template Support

Branch

  • feature/empty-content-template-placeholders

Commit Breakdown

  1. ec9385e62 - feat(model): add document empty content placeholder API
  2. a10f855a6 - feat(avalonia): render empty content templates for document hosts
  3. b3a20bdb8 - test(leaks): cover empty-content subscription detach paths
  4. 6febd2130 - docs: document empty-content support for tabbed and mdi hosts

Problem

Document hosts had no first-class placeholder content experience when empty, and there was no control-level template override for rendering empty host content in tabbed and MDI views. This also required explicit subscription lifecycle validation to ensure no leaks when DataContext/collections change.

Solution Overview

Implemented end-to-end empty-host support across model, Avalonia controls, templates, tests, and docs:

  • Added model-level placeholder API on document docks.
  • Added Avalonia control-level template override (EmptyContentTemplate) for:
    • DocumentControl (tabbed documents)
    • MdiDocumentControl (MDI documents)
  • Added host visibility state tracking in controls to switch between real document surface and empty placeholder host.
  • Added headless and leak tests covering all new code paths (including collection/data-context swap and detach cleanup).
  • Updated docs/reference pages to describe the new API and behavior.

Detailed Changes

1) Model/API changes

  • Added object? EmptyContent { get; set; } to IDocumentDock.
  • Added fluent extension:
    • WithEmptyContent(this IDocumentDock dock, object? content)
  • Added default empty-content value ("No documents open") across document dock implementations:
    • Dock.Model.Avalonia.Controls.DocumentDock
    • Dock.Model.CaliburMicro.Controls.DocumentDock
    • Dock.Model.Inpc.Controls.DocumentDock
    • Dock.Model.Mvvm.Controls.DocumentDock
    • Dock.Model.Prism.Controls.DocumentDock
    • Dock.Model.ReactiveProperty.Controls.DocumentDock
    • Dock.Model.ReactiveUI.Controls.DocumentDock

2) Avalonia controls and templates

  • DocumentControl

    • Added styled property: EmptyContentTemplate.
    • Added direct property: HasVisibleDockables.
    • Added subscription lifecycle handling for DataContext + visible dockables collection.
    • Added placeholder host in fluent template (PART_EmptyContentHost) bound to model EmptyContent and control EmptyContentTemplate.
    • Added content/placeholder visibility switching based on HasVisibleDockables.
  • MdiDocumentControl

    • Added styled property: EmptyContentTemplate.
    • Added direct property: HasVisibleDocuments.
    • Added subscription lifecycle handling for DataContext + visible dockables collection.
    • Added placeholder host in fluent template (PART_EmptyContentHost) bound to model EmptyContent and control EmptyContentTemplate.
    • Added MDI items host visibility switching based on HasVisibleDocuments.

3) Test coverage

Headless functional tests

  • DocumentEmptyContentTests

    • shows placeholder when empty
    • hides placeholder when docs exist
    • updates on add/remove transitions
    • applies custom EmptyContentTemplate
  • MdiEmptyContentTests

    • same scenarios as above for MDI host
  • DocumentDockPropertiesTests

    • validates default EmptyContent

Subscription/leak-path tests

  • ControlSubscriptionLeakTests (headless)

    • validates subscription detach behavior on:
      • DataContext swaps
      • VisibleDockables collection replacement
      • control detach from visual tree
  • EmptyContentSubscriptionLeakTests (release leak suite)

    • mirrors detach/swap/replace scenarios for both tabbed and MDI controls

Model/serializer test updates

  • Added/updated tests in:
    • Dock.Model.CaliburMicro.UnitTests
    • Dock.Model.Mvvm.UnitTests
    • Dock.Model.Prism.UnitTests
    • Dock.Model.ReactiveProperty.UnitTests
    • Dock.Model.ReactiveUI.UnitTests
    • Dock.Model.UnitTests (fluent extension)
    • Dock.Serializer.UnitTests (INPC default)

4) Documentation updates

Updated docs to include new API/properties and behavior:

  • docfx/articles/dock-controls-reference.md
  • docfx/articles/dock-mdi.md
  • docfx/articles/dock-model-controls.md
  • docfx/articles/dock-reference.md

Validation Performed

Executed targeted tests on this branch:

  • dotnet test tests/Dock.Avalonia.HeadlessTests/Dock.Avalonia.HeadlessTests.csproj -c Release --filter "FullyQualifiedName~DocumentEmptyContentTests|FullyQualifiedName~MdiEmptyContentTests|FullyQualifiedName~DocumentDockPropertiesTests|FullyQualifiedName~ControlSubscriptionLeakTests"

    • Result: Passed (18 tests)
  • dotnet test tests/Dock.Avalonia.LeakTests/Dock.Avalonia.LeakTests.csproj -c Release --filter "FullyQualifiedName~EmptyContentSubscriptionLeakTests"

    • Result: Passed (2 tests)
  • dotnet test tests/Dock.Model.UnitTests/Dock.Model.UnitTests.csproj -c Release --filter "FullyQualifiedName~DocumentDockFluentExtensionsTests"

    • Result: Passed (1 test)
  • dotnet test tests/Dock.Serializer.UnitTests/Dock.Serializer.UnitTests.csproj -c Release --filter "FullyQualifiedName~DocumentDockInpcTests"

    • Result: Passed (1 test)

Behavioral Notes

  • EmptyContentTemplate was implemented in Avalonia control layer (not model layer), matching existing template override patterns.
  • Placeholder rendering now applies to both:
    • Tabbed document host (DocumentControl)
    • MDI document host (MdiDocumentControl)

Risk Assessment

Low to medium:

  • Core behavior gated behind empty/non-empty host state.
  • New subscriptions are explicitly detached and covered by leak-focused tests.
  • Model API addition is additive and backward-compatible.

Reviewer Checklist

  • Verify control-template behavior in both tabbed and MDI empty states.
  • Confirm custom EmptyContentTemplate visuals in sample app or manual harness.
  • Confirm no regressions in document activation/visibility transitions.
  • Confirm docs/reference pages are aligned with implemented API.

@wieslawsoltes wieslawsoltes merged commit 20ae3b5 into master Feb 9, 2026
5 checks passed
@wieslawsoltes wieslawsoltes deleted the feature/empty-content-template-placeholders branch February 9, 2026 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant