Files

107 lines
6.2 KiB
Markdown
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- Common/DTS.Common/RegionManager/RegionAdapters/StackPanelRegionAdapter.cs
- Common/DTS.Common/RegionManager/RegionAdapters/ViewerStackPanelRegionAdapter.cs
generated_at: "2026-04-16T03:27:23.682098+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "46a3e6b99bc63fd1"
---
# RegionAdapters
## Documentation: `StackPanelRegionAdapter` and `ViewerStackPanelRegionAdapter`
---
### 1. Purpose
This module provides two Prism region adapters—`StackPanelRegionAdapter` and `ViewerStackPanelRegionAdapter`—that enable Prism region management (view registration, activation, and removal) to work with WPF `StackPanel` controls. Both adapters synchronize the `Views` collection of a Prism `IRegion` with the `Children` collection of a `StackPanel`, enabling declarative region usage in XAML (e.g., `<prism:RegionManager.RegionName>...</prism:RegionManager.RegionName>` attached to a `StackPanel`). They are used to host dynamic, stack-ordered UI content in Prism-based views, with `ViewerStackPanelRegionAdapter` likely reserved for specialized viewer scenarios (e.g., document/image viewers), though its behavior is currently identical to `StackPanelRegionAdapter`.
---
### 2. Public Interface
Both classes are public and inherit from `Prism.Regions.RegionAdapterBase<StackPanel>`. They expose only the base constructor and the two overridden abstract methods.
#### `StackPanelRegionAdapter`
- **Constructor**
```csharp
public StackPanelRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
```
Initializes a new instance of `StackPanelRegionAdapter`, passing `regionBehaviorFactory` to the base class.
- **`Adapt` (protected override)**
```csharp
protected override void Adapt(IRegion region, StackPanel regionTarget)
```
Attaches a `CollectionChanged` handler to `region.Views`. On `Add`, appends each new `UIElement` in `e.NewItems` to `regionTarget.Children`. On `Remove`, removes each `UIElement` in `e.OldItems` from `regionTarget.Children` *if present*. Does nothing if `region` is `null`.
- **`CreateRegion` (protected override)**
```csharp
protected override IRegion CreateRegion()
```
Returns a new instance of `AllActiveRegion`, meaning all views added to the region are active simultaneously (no activation/deactivation semantics).
#### `ViewerStackPanelRegionAdapter`
- **Constructor**
```csharp
public ViewerStackPanelRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
```
Identical to `StackPanelRegionAdapter` constructor.
- **`Adapt` (protected override)**
```csharp
protected override void Adapt(IRegion region, StackPanel regionTarget)
```
*Behaviorally identical* to `StackPanelRegionAdapter.Adapt`.
- **`CreateRegion` (protected override)**
```csharp
protected override IRegion CreateRegion()
```
*Behaviorally identical* to `StackPanelRegionAdapter.CreateRegion`.
> **Note**: No additional public methods, properties, or events are defined in either class.
---
### 3. Invariants
- **Null Safety**: `Adapt` exits early if `region == null`; no exception is thrown.
- **Child Management**:
- Views are *always* added to the end of `StackPanel.Children` (order preserved by `Add`).
- Views are *only* removed if `regionTarget.Children.Contains(element)` returns `true`; silent no-op otherwise.
- No deduplication or uniqueness enforcement: adding the same `UIElement` instance multiple times (e.g., via multiple `Add` actions) will result in multiple children.
- **Region Type**: All regions created via `CreateRegion()` are `AllActiveRegion` instances, meaning:
- All views in the region are considered active.
- No view activation/deactivation lifecycle is enforced by the region itself.
- **Event Subscription**: The `CollectionChanged` handler is attached *once* per `Adapt` call and is never detached. Repeated calls to `Adapt` on the same `StackPanel` (e.g., due to re-adapter registration) will result in multiple handlers and duplicate operations.
---
### 4. Dependencies
#### Dependencies *of* this module:
- **Prism Framework**: Specifically `Prism.Regions.RegionAdapterBase<T>` and `Prism.Regions.IRegionBehaviorFactory`, `IRegion`, `AllActiveRegion`.
- **WPF**: `System.Windows.Controls.StackPanel`, `System.Windows.UIElement`.
- **.NET Collections**: `System.Collections.Specialized.NotifyCollectionChangedAction`, `NotifyCollectionChangedEventArgs`.
#### Dependencies *on* this module:
- Likely consumed by Prism region registration logic (e.g., `RegionAdapterMappings`) to map `StackPanel` targets to these adapters.
- `ViewerStackPanelRegionAdapter` suggests a domain-specific usage (e.g., in viewer modules), but no explicit consumers are visible in the source.
---
### 5. Gotchas
- **Duplicate Event Handlers**: Since `Adapt` does not detach previous handlers, re-adapter registration (e.g., due to module reload or re-initialization) will cause `CollectionChanged` events to be processed multiple times per change, leading to duplicate additions/removals or exceptions (e.g., `ArgumentException` if `Children.Remove` is called on a non-child). This is a critical risk if the adapter is registered multiple times.
- **No Cleanup**: No `IDisposable` implementation or handler unsubscription occurs. Long-lived `StackPanel`s with short-lived regions may leak memory if the region is garbage-collected but the handler remains attached.
- **Redundant Variable Assignment**: In `Remove` handling, `var element = elementLoopVariable;` is unnecessary (no closure or loop-scope issue in C# 5+), suggesting legacy or defensive coding.
- **Identical Implementations**: `StackPanelRegionAdapter` and `ViewerStackPanelRegionAdapter` have *identical* logic. Unless future divergence is intended, this duplication is technical debt. The naming implies a semantic distinction (e.g., viewer-specific behavior), but none is implemented.
- **No Exception Handling**: If `Children.Add` or `Children.Remove` throws (e.g., due to cross-thread access or invalid element), the exception propagates unhandled.
- **Assumes `StackPanel.Children` is Mutable**: Relies on `StackPanel.Children` being a standard `UIElementCollection`. Custom or mocked `StackPanel` subclasses with non-standard children collections may behave unexpectedly.
> **None identified from source alone** for *other* non-obvious behavior beyond the above.