--- source_files: - Common/DTS.CommonCore/RegionManager/RegionAdapters/StackPanelRegionAdapter.cs - Common/DTS.CommonCore/RegionManager/RegionAdapters/ViewerStackPanelRegionAdapter.cs generated_at: "2026-04-16T02:50:38.403475+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "01eecd59b616feb7" --- # RegionAdapters ## 1. Purpose This module provides custom Prism region adapters for integrating WPF `StackPanel` controls into the Prism region management system. Specifically, it enables views to be dynamically added to and removed from a `StackPanel` via Prism’s region abstraction, maintaining synchronization between the region’s view collection and the `StackPanel`’s `Children` collection. Two adapters exist: `StackPanelRegionAdapter` (general-purpose) and `ViewerStackPanelRegionAdapter` (likely intended for specialized viewer scenarios), both implementing identical adaptation logic but registered as distinct types—suggesting potential future divergence or explicit separation of concerns in the system’s region management strategy. ## 2. Public Interface ### `StackPanelRegionAdapter` - **Constructor**: `public StackPanelRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)` Initializes a new instance, passing the behavior factory to the base `RegionAdapterBase` constructor. - **`Adapt` method** (override): `protected override void Adapt(IRegion region, StackPanel regionTarget)` Subscribes to the `CollectionChanged` event of `region.Views`. On `Add`, appends new `UIElement` instances to `regionTarget.Children`; on `Remove`, removes matching elements from `regionTarget.Children` (if present). Does nothing if `region` is `null`. - **`CreateRegion` method** (override): `protected override IRegion CreateRegion()` Returns a new `AllActiveRegion` instance, meaning all views in the region are kept active (not deactivated/destroyed on removal). ### `ViewerStackPanelRegionAdapter` - **Constructor**: `public ViewerStackPanelRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)` Identical to `StackPanelRegionAdapter`; passes `regionBehaviorFactory` to the base constructor. - **`Adapt` method** (override): `protected override void Adapt(IRegion region, StackPanel regionTarget)` Identical behavior to `StackPanelRegionAdapter.Adapt`. - **`CreateRegion` method** (override): `protected override IRegion CreateRegion()` Identical behavior to `StackPanelRegionAdapter.CreateRegion`; returns `AllActiveRegion`. ## 3. Invariants - `regionTarget` (the `StackPanel`) must be non-null when `Adapt` is called (though `region` may be `null`, in which case the method exits early). - Views added to the region are appended to the *end* of `StackPanel.Children` in the order they appear in `e.NewItems`. - Views removed from the region are removed from `StackPanel.Children` *only if* they are currently present in the collection (no exception thrown if missing). - The `AllActiveRegion` returned by `CreateRegion()` ensures all views remain active; no view deactivation occurs on removal—only visual removal from the `StackPanel`. - The `CollectionChanged` event handler is attached exactly once per `Adapt` call (no duplicate subscriptions are prevented). ## 4. Dependencies - **Depends on**: - `Microsoft.Practices.Prism.Regions` (Prism library), specifically `RegionAdapterBase`, `IRegion`, `IRegionBehaviorFactory`, and `AllActiveRegion`. - `System.Windows` and `System.Windows.Controls` (WPF), for `StackPanel`, `UIElement`, and `CollectionChanged` event handling. - **Used by**: - Prism’s region management system (via `RegionAdapterMappings` or similar registration), where `StackPanel` targets are mapped to these adapters. - Likely consumed by UI modules that use `StackPanel` as a layout container for dynamic view injection (e.g., tool windows, viewer panes). - `ViewerStackPanelRegionAdapter` suggests a dedicated path for viewer-related regions (e.g., medical imaging, CAD, or data visualization contexts), though its usage is not explicit in the source. ## 5. Gotchas - **No deduplication or ordering guarantees**: If the same view is added multiple times to the region (e.g., via duplicate `Add` notifications), it will be added multiple times to `StackPanel.Children`. - **No cleanup on adapter disposal**: The `CollectionChanged` event handler is attached but never detached. If `Adapt` is called multiple times on the same `StackPanel` instance (e.g., due to region recreation), multiple handlers will accumulate, causing duplicate additions/removals per event. - **`AllActiveRegion` behavior may be unexpected**: Views removed from the region remain in memory (as `AllActiveRegion` does not deactivate them), but they are only visually removed from the `StackPanel`. This could lead to memory leaks if views hold unmanaged resources. - **Identical implementations**: The near-identical code in `StackPanelRegionAdapter` and `ViewerStackPanelRegionAdapter` suggests possible technical debt or incomplete refactoring. Without additional context (e.g., future plans for divergent behavior), the duplication is unjustified. - **No handling for `Replace` or `Reset` actions**: Only `Add` and `Remove` actions are handled; `NotifyCollectionChangedAction.Replace` or `Reset` will be silently ignored, potentially leaving the `StackPanel` out of sync with the region.