Skip to content

ItemsSource Container Generator Extensibility#1037

Merged
wieslawsoltes merged 4 commits intomasterfrom
feature/itemsource-container-generator-complete
Feb 10, 2026
Merged

ItemsSource Container Generator Extensibility#1037
wieslawsoltes merged 4 commits intomasterfrom
feature/itemsource-container-generator-complete

Conversation

@wieslawsoltes
Copy link
Owner

PR Summary: ItemsSource Container Generator Extensibility

Branch

  • feature/itemsource-container-generator-complete

Commit Breakdown

  1. 857b3c6ca - Add extensible ItemsSource container generator pipeline
  2. be760b2ca - Add unit, headless, and leak tests for container generators
  3. e906474d0 - Update ReactiveUI ItemsSource sample for custom generators
  4. 9ca84b3e1 - Document ItemsSource generator APIs and behavior

Problem

DocumentDock.ItemsSource and ToolDock.ItemsSource had template-driven generation but no unified, explicit container generation contract similar to item-container override hooks. Custom container type creation, per-item preparation, and cleanup were not first-class extension points.

Solution

Introduced a dedicated container generator contract and integrated it into both source-backed pipelines:

  • New shared contract: IDockItemContainerGenerator
  • Per-dock override: ItemContainerGenerator on both document and tool ItemsSource docks
  • New default implementation: DockItemContainerGenerator
  • Pipeline integration in DocumentDock and ToolDock for add/remove/replace/reset and generator swaps
  • Explicit cleanup tracking to ensure generator ownership is respected across runtime generator changes

API Additions and Changes

New Interface

  • src/Dock.Model/Core/IDockItemContainerGenerator.cs
    • CreateDocumentContainer
    • PrepareDocumentContainer
    • ClearDocumentContainer
    • CreateToolContainer
    • PrepareToolContainer
    • ClearToolContainer

Updated Contracts

  • src/Dock.Model/Core/IItemsSourceDock.cs
    • Added IDockItemContainerGenerator? ItemContainerGenerator { get; }
  • src/Dock.Model/Core/IToolItemsSourceDock.cs
    • Added IDockItemContainerGenerator? ItemContainerGenerator { get; }

New Default Generator

  • src/Dock.Model.Avalonia/Controls/DockItemContainerGenerator.cs
    • Default behavior for title/can-close/context mapping
    • Uses DocumentTemplate/ToolTemplate content when available
    • Provides fallback content factories
    • Exposes virtual methods for targeted overrides

Runtime Behavior

DocumentDock and ToolDock Integration

  • Both docks now resolve generator as:
    • custom ItemContainerGenerator when assigned
    • otherwise DockItemContainerGenerator.Default
  • Generation calls Create*Container then Prepare*Container
  • Cleanup calls Clear*Container
  • Regeneration occurs on:
    • ItemsSource change
    • ItemContainerGenerator change
    • (ToolDock) ToolTemplate change
  • Generated container tracking now records the generator instance used to create each container, so cleanup routes back to the correct generator after runtime swaps.

Safety/Interop Guards

  • Document path rejects containers not implementing IDocument
  • Tool path rejects containers not implementing ITool
  • Invalid containers are cleared and not added to dock collections

Test Coverage

New Unit/Headless Tests

  • tests/Dock.Model.Avalonia.UnitTests/Controls/DockItemContainerGeneratorTests.cs

    • Custom container generation for documents and tools
    • Content binding and context mapping assertions
    • Close-to-source removal behavior
    • Generator swap regeneration
    • Add/remove/replace/reset tracking across source mutations
    • Interop with manual dockables during source swaps
    • Invalid container rejection paths
  • tests/Dock.Model.Avalonia.UnitTests/Controls/DocumentDockItemsSourceUITests.cs

    • Added headless scenario asserting custom generator container type and preparation markers

New Leak Tests

  • tests/Dock.Avalonia.LeakTests/DockItemContainerGeneratorLeakTests.cs
    • Verifies no leaked generator references after generator swap in DocumentDock
    • Verifies no leaked generator references after generator swap in ToolDock

Sample Updates

Updated the ReactiveUI ItemsSource sample to demonstrate real custom generator usage:

  • samples/DockReactiveUIItemsSourceSample/Infrastructure/SampleDockItemContainerGenerator.cs

    • Custom generated Document/Tool derived container types
    • Custom title shaping and source index metadata
  • samples/DockReactiveUIItemsSourceSample/Views/MainWindow.axaml

    • Wires SampleDockItemContainerGenerator directly into both docks
    • Uses generated container types in x:DataType
    • Displays SourceIndex to confirm custom generator path at runtime
  • samples/DockReactiveUIItemsSourceSample/ViewModels/MainWindowViewModel.cs

    • Updated seed text to describe custom container generator behavior

Documentation Updates

  • docfx/articles/dock-itemssource.md

    • Added generator behavior, customization points, and default/override semantics
  • docfx/articles/dock-model-controls.md

    • Added IItemsSourceDock / IToolItemsSourceDock + generator contract details
  • docfx/articles/dock-reference.md

    • Added API-level reference for ItemContainerGenerator and DockItemContainerGenerator

Validation

Executed and passed:

  1. dotnet test tests/Dock.Model.Avalonia.UnitTests/Dock.Model.Avalonia.UnitTests.csproj -v minimal
    • Passed: 128
  2. dotnet test tests/Dock.Avalonia.LeakTests/Dock.Avalonia.LeakTests.csproj -c Release -v minimal
    • Passed: 122
  3. dotnet build samples/DockReactiveUIItemsSourceSample/DockReactiveUIItemsSourceSample.csproj -v minimal
    • Build succeeded

Net Diff (branch vs origin/master)

  • 15 files changed
  • 1263 insertions
  • 239 deletions

@wieslawsoltes wieslawsoltes merged commit 619e90d into master Feb 10, 2026
9 checks passed
@wieslawsoltes wieslawsoltes deleted the feature/itemsource-container-generator-complete branch February 10, 2026 20:01
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