Files
DP44/enriched-partialglm/Common/DTS.CommonCore/RibbonControl.md
2026-04-17 14:55:32 -04:00

131 lines
7.8 KiB
Markdown

---
source_files:
- Common/DTS.CommonCore/RibbonControl/RibbonControlSelectionChanged.cs
- Common/DTS.CommonCore/RibbonControl/RibbonControlOperation.cs
- Common/DTS.CommonCore/RibbonControl/RibbonControlSelectionEventArgs.cs
- Common/DTS.CommonCore/RibbonControl/RibbonControlSelectionChangeBehavior.cs
- Common/DTS.CommonCore/RibbonControl/RibbonRegionAdapter.cs
generated_at: "2026-04-16T12:05:40.425898+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "c0e1c8bd7f1a18f4"
---
# RibbonControl Module Documentation
## 1. Purpose
This module provides Prism region adapter infrastructure for integrating WPF `Ribbon` controls with the Prism navigation and region system. It enables dynamic addition and removal of `RibbonTab` and `RibbonApplicationMenu` items, synchronizes tab selection between document/workspace views and the Ribbon, and publishes selection change events through the Prism event aggregator for loose coupling between UI components.
---
## 2. Public Interface
### `RibbonControlSelectionChanged`
**Kind:** Event class
**Signature:** `public class RibbonControlSelectionChanged : CompositePresentationEvent<RibbonControlSelectionEventArgs>`
**Behavior:** A Prism event used to broadcast when a Ribbon's selection has changed. Carries `RibbonControlSelectionEventArgs` payload indicating whether an item was added or removed.
---
### `RibbonControlOperation`
**Kind:** Enumeration
**Values:**
- `AddedItem` — Indicates an item was added to the control
- `RemovedItem` — Indicates an item was removed from the control
**Behavior:** Used within `RibbonControlSelectionEventArgs` to describe the type of selection operation.
---
### `RibbonControlSelectionEventArgs`
**Kind:** Event arguments class
**Constructor:** `public RibbonControlSelectionEventArgs(RibbonControlOperation operation, object item)`
**Properties:**
| Property | Type | Access |
|----------|------|--------|
| `Operation` | `RibbonControlOperation` | `get;` (set via constructor) |
| `Item` | `object` | `get;` (set via constructor) |
**Behavior:** Immutable payload carrying the operation type and the affected item for ribbon selection changes.
---
### `RibbonControlSelectionChangeBehavior`
**Kind:** WPF Behavior (`System.Windows.Interactivity.Behavior<Ribbon>`)
**Attached Property:** `public static readonly DependencyProperty TargetRibbonProperty`
**Properties:**
| Property | Type | Access |
|----------|------|--------|
| `TargetRibbonControl` | `Ribbon` | `get; set;` |
**Methods:**
- `protected override void OnAttached()` — Subscribes to `AssociatedObject.SelectionChanged`; resolves `IEventAggregator` via `ServiceLocator.Current`
- `protected override void OnDetaching()` — Unsubscribes from `AssociatedObject.SelectionChanged`
- `void Ribbon_SelectionChanged(object sender, SelectionChangedEventArgs e)` — Publishes `RibbonControlSelectionChanged` events for each added/removed item
**Behavior:** When attached to a `Ribbon`, intercepts selection changes and publishes `RibbonControlSelectionChanged` events. Publishes separate events for added items (first item from `AddedItems`) and removed items (first item from `RemovedItems`).
---
### `RibbonRegionAdapter`
**Kind:** Prism RegionAdapter (`RegionAdapterBase<Ribbon>`, `IDisposable`)
**Constructor:** `public RibbonRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory, IRegionManager regionManager, IEventAggregator eventAggregator)`
**Methods:**
| Method | Visibility | Description |
|--------|------------|-------------|
| `Adapt(IRegion region, Ribbon regionTarget)` | `protected override` | Wires up `ActiveViews.CollectionChanged` to add/remove `RibbonTab` and `RibbonApplicationMenu` items |
| `CreateRegion()` | `protected override` | Returns new `AllActiveRegion` instance |
| `OnTabControlSelectionChanged(TabControlSelectionEventArgs e)` | `private` | Handles `TabControlSelectionChanged` events to sync Ribbon tab selection |
| `Dispose()` | `public` | Unsubscribes from `TabControlSelectionChanged` event |
**Behavior:** Adapts a `Ribbon` control to a Prism region. Handles `RibbonTab` additions (with auto-generated `Uid`, `TabIndex` sorting, and optional default selection via config), `RibbonApplicationMenu` additions, and `RibbonTab` removals. Listens to `TabControlSelectionChanged` events to activate corresponding Ribbon tabs when views implementing `IRibbonTabInfoProvider` are activated.
---
## 3. Invariants
1. **Null Region Target:** `Adapt()` throws `ArgumentNullException` if `regionTarget` is null.
2. **Region Type:** `CreateRegion()` always returns a new `AllActiveRegion` instance.
3. **Uid Generation:** If a `RibbonTab` or `RibbonApplicationMenu` has a null or empty `Uid`, one is auto-generated using `Guid.NewGuid().GetHashCode().ToString(CultureInfo.InvariantCulture)`.
4. **Tab Sorting:** All `RibbonTab` items added to the region are sorted by `TabIndex` in ascending order.
5. **Single Item Publication:** `RibbonControlSelectionChangeBehavior.Ribbon_SelectionChanged` publishes at most one event for added items (index 0) and one for removed items (index 0), regardless of how many items are in the collections.
6. **Event Subscription Lifecycle:** `RibbonRegionAdapter` unsubscribes from `TabControlSelectionChanged` on disposal.
---
## 4. Dependencies
### This module depends on:
- `Microsoft.Practices.Prism.Events``CompositePresentationEvent`, `IEventAggregator`
- `Microsoft.Practices.Prism.Regions``RegionAdapterBase<T>`, `IRegion`, `IRegionBehaviorFactory`, `IRegionManager`, `AllActiveRegion`
- `Microsoft.Practices.ServiceLocation``ServiceLocator`
- `Microsoft.Windows.Controls.Ribbon``Ribbon`, `RibbonTab`, `RibbonApplicationMenu`
- `System.Windows.Interactivity``Behavior<T>`
- `System.Configuration``ConfigurationManager`
- `DTS.Common.Classes``IRibbonTabInfoProvider` (referenced but not in source)
- `DTS.Common.Enums``TabControlOperation` (referenced but not in source)
- `DTS.Common.Events``TabControlSelectionChanged` event class (referenced but not in source)
- `DTS.Common.Base``IBaseView` interface (referenced but not in source)
### What depends on this module:
- Cannot be determined from source alone; consumers would reference `RibbonRegionAdapter` in Prism bootstrapping/configuration and use `RibbonControlSelectionChanged` event for cross-component communication.
---
## 5. Gotchas
1. **Naming Inconsistency:** The XML documentation comment in `RibbonControlSelectionEventArgs.cs` references "TabControlSelectionChanged" while the actual class is `RibbonControlSelectionChanged`. This may cause confusion.
2. **ServiceLocator vs Constructor Injection:** `RibbonControlSelectionChangeBehavior` resolves `IEventAggregator` via `ServiceLocator.Current.GetInstance<IEventAggregator>()` (service locator pattern), while `RibbonRegionAdapter` receives it via constructor injection. This inconsistency may cause issues in testing or if service locator is not configured.
3. **Partial Lock Coverage:** `AddRibbonTabToRegion()` uses a lock object for thread safety when modifying `regionTarget.Items`, but `RemoveRibbonTabFromRibbonRegion()` does not. This could lead to race conditions in multi-threaded scenarios.
4. **Case-Insensitive Comparison via ToLower():** The `DefaultRibbonTab` configuration comparison uses `ToLower()` on both sides rather than using `StringComparison.OrdinalIgnoreCase`, which is the preferred .NET idiom.
5. **Only First Item Published:** The behavior only publishes events for `e.AddedItems[0]` and `e.RemovedItems[0]`. If multiple items are added/removed in a single selection change, subsequent items are silently ignored.
6. **External Interface Dependencies:** `RibbonRegionAdapter.OnTabControlSelectionChanged()` depends on `IRibbonTabInfoProvider`, `IBaseView`, `TabControlSelectionChanged`, and `TabControlOperation` which are not included in the provided source files. Their contracts are inferred but not documented here.