--- source_files: - Common/DTS.CommonCore/BusyIndicatorManager/xBusyIndicator.xaml.cs - Common/DTS.CommonCore/BusyIndicatorManager/BusyIndicatorManager.cs generated_at: "2026-04-16T11:56:30.835743+00:00" model: "zai-org/GLM-5-FP8" schema_version: 1 sha256: "85046dce961f12c2" --- # Documentation: DTS.Common.BusyIndicatorManager ## 1. Purpose This module provides a centralized mechanism for managing busy indicator UI state across an application. It implements a singleton-based manager (`BusyIndicatorManager`) that tracks multiple concurrent busy operations by unique ID, allowing different parts of the application to show/hide busy indicators without conflicting with each other. The `xBusyIndicator` class serves as a WPF user control for displaying the busy indicator UI. --- ## 2. Public Interface ### `BusyIndicatorManager` (class) **Inherits from:** `NotificationObject` (Microsoft.Practices.Prism.ViewModel) #### Singleton Access ```csharp public static BusyIndicatorManager Instance { get; } ``` Returns the singleton instance of `BusyIndicatorManager`. Thread-safe via lock synchronization on `SyncRoot`. #### Properties ```csharp public bool IsBusy { get; } ``` Indicates whether any busy operation is currently active. Read-only from external callers; set internally via `ShowBusy`/`CloseBusy`. Raises `PropertyChanged` notification. ```csharp public string Message { get; } ``` The current message to display in the busy indicator. Read-only from external callers. Raises `PropertyChanged` notification. #### Methods ```csharp public void ShowBusy(int id, string busyMessage) ``` Registers a busy operation with the given `id` and displays `busyMessage`. If the `id` already exists, updates the message. Sets `IsBusy` to `true` and updates `Message`. ```csharp public void CloseBusy(int id) ``` Removes the busy operation identified by `id`. If no busy operations remain, sets `IsBusy` to `false` and clears `Message`. If other operations remain, keeps `IsBusy` as `true` and sets `Message` to the last entry's value in `busyParameters`. --- ### `xBusyIndicator` (class) **Inherits from:** Not explicitly shown; appears to be a WPF partial class (likely `UserControl`). ```csharp public xBusyIndicator() ``` Default constructor that calls `InitializeComponent()`. ```csharp public void Connect(int connectionId, object target) ``` Method present in the class but **implementation is empty**. Purpose unclear from source alone. --- ## 3. Invariants - **Singleton guarantee:** Only one instance of `BusyIndicatorManager` can exist per process. Access is always through `BusyIndicatorManager.Instance`. - **Thread-safe initialization:** The singleton is lazily initialized with lock-based synchronization. - **ID uniqueness:** Each busy operation is identified by a unique `int` ID. Callers are responsible for ensuring IDs do not collide. - **State consistency:** `IsBusy` is `true` if and only if `busyParameters.Count > 0`. - **Message consistency:** When `IsBusy` is `false`, `Message` is an empty string. When `IsBusy` is `true`, `Message` reflects the most recently added/updated busy message. - **Property change notifications:** `IsBusy` and `Message` raise `PropertyChanged` via `RaisePropertyChanged()` when modified. --- ## 4. Dependencies ### This module depends on: - `Microsoft.Practices.Prism.ViewModel` — specifically `NotificationObject` for `INotifyPropertyChanged` implementation - `System.Collections.Generic` — `Dictionary` - `System.Linq` — `Enumerable.Last()` extension method - `System.Windows.Controls` — referenced in `xBusyIndicator` - `Xceed.Wpf.Toolkit` — referenced in `xBusyIndicator` (likely provides the actual busy indicator control) ### What depends on this module: - **Cannot be determined from source alone.** Consumers would bind to `BusyIndicatorManager.Instance.IsBusy` and `Message` properties, or instantiate `xBusyIndicator` in XAML views. --- ## 5. Gotchas 1. **`xBusyIndicator.Connect` is empty:** The method signature suggests it may be generated code (common in WPF for `IComponentConnector`), but the empty implementation has no documented purpose. 2. **Dictionary ordering assumption:** `CloseBusy` uses `busyParameters.Last().Value` to determine the next message to display. While .NET Framework 4.7+ and .NET Core preserve insertion order in `Dictionary`, this is not guaranteed by the interface contract. The "last" message may not be the most recently added in all runtime environments. 3. **No validation of `busyMessage`:** `ShowBusy` accepts any string, including `null` or empty strings, without validation. 4. **No exception handling for missing IDs in `CloseBusy`:** The method silently ignores calls to close non-existent IDs (it checks `ContainsKey` before removing). 5. **Message always updated on `ShowBusy`:** Even if an ID already exists with the same message, `Message` is reassigned and property change notification fires, which may trigger unnecessary UI updates.