Files
DP44/enriched-qwen3-coder-next/DataPRO/Modules/Menu/HamburgerMenu/ViewModel.md
2026-04-17 14:55:32 -04:00

136 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
source_files:
- DataPRO/Modules/Menu/HamburgerMenu/ViewModel/HamburgerMenuViewModel.cs
generated_at: "2026-04-16T04:48:30.206063+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "462d2b26bf58cd93"
---
# ViewModel
## Documentation: `HamburgerMenuViewModel`
---
### 1. **Purpose**
The `HamburgerMenuViewModel` class serves as the MVVM-compliant view model for the applications hamburger menu UI component. It manages the state and behavior of the menu—including item list, enabled/disabled status, busy state, and context menu construction—while acting as a bridge between the view (`IHamburgerMenuView`) and the broader system via Prisms event aggregation and Unity dependency injection. It subscribes to system-wide events (e.g., test lifecycle, busy indicators, notifications) to dynamically update its state and exposes interaction requests for modal UI (notifications, confirmations). It is a shared singleton (per container) responsible for rendering a context menu populated from a string array and raising a delegate when menu items are selected.
---
### 2. **Public Interface**
- **`IHamburgerMenuView View { get; set; }`**
Reference to the associated view; set during construction and used to bind `DataContext`.
- **`InteractionRequest<Notification> NotificationRequest { get; }`**
Prism interaction request used to trigger notification popups (e.g., informational messages).
- **`InteractionRequest<Confirmation> ConfirmationRequest { get; }`**
Prism interaction request used to trigger confirmation dialogs (e.g., yes/no prompts).
- **`event PropertyChangedEventHandler PropertyChanged;`**
Standard `INotifyPropertyChanged` implementation for data binding.
- **`void OnPropertyChanged(string propertyName);`**
Raises the `PropertyChanged` event for the specified property.
- **`ContextMenu GetContextMenu();`**
Returns the lazily-built `ContextMenu` instance. Builds it on first call if not already constructed. Thread-safe via `lock(MyLock)`.
- **`void SetMenuItems(string[] items);`**
Sets the list of menu item labels and immediately rebuilds the context menu.
- **`void ClearMenuItems();`**
Clears the internal `_menuItems` array and triggers a rebuild (resulting in an empty menu).
- **`void EnableMenu(bool enable);`**
Sets `IsEnabled` to `enable`, updating the UI state.
- **`void Unset();`**
Currently empty; no-op.
- **`void OnSetActive();`**
Currently empty; no-op.
- **`void Cleanup();`**
Currently empty; no-op.
- **`Task CleanupAsync();`**
Returns `Task.CompletedTask`; no-op.
- **`void Initialize();`**
Overload variants (`Initialize()`, `Initialize(object)`, `Initialize(object, object)`) are present but all currently no-op.
- **`Task InitializeAsync();`**
Overload variants (`InitializeAsync()`, `InitializeAsync(object)`) are present but all return `Task.CompletedTask`; no-op.
- **`void Activated();`**
Currently empty; no-op.
- **`bool IsEnabled { get; private set; }`**
Indicates whether the menu is enabled. Default `true`. Updated via `EnableMenu()`, `OnTestEvent()`, or internal logic.
- **`bool IsBusy { get; set; }`**
Indicates whether the menu is in a busy state (e.g., during test execution). Bound to `BusyIndicatorChangeNotification` event.
- **`bool IsMenuIncluded { get; set; }`**
Indicates whether the hamburger menu is included in the UI. Not used internally—likely for view-level visibility binding.
- **`bool IsNavigationIncluded { get; set; }`**
Indicates whether navigation controls are included in the UI. Not used internally—likely for view-level visibility binding.
- **`MenuItemPressedDelegate MenuItemPressed { get; set; }`**
Delegate invoked when a menu item is pressed. Signature: `void Delegate(string id)`. The `id` passed is the `Header` of the selected `MenuItem`.
---
### 3. **Invariants**
- `View.DataContext` is always set to `this` in the constructor.
- `_contextMenu` is lazily initialized on first call to `GetContextMenu()` and rebuilt only when `_menuItems` changes (via `SetMenuItems()` or `ClearMenuItems()`).
- `_menuItems` is never `null`; it is initialized to `new string[0]` and cleared to `new string[0]`.
- `IsEnabled` defaults to `true`.
- `IsBusy` is updated synchronously on the publisher thread (via `ThreadOption.PublisherThread`) in response to `BusyIndicatorChangeNotification`.
- Thread safety for context menu construction is ensured via `lock(MyLock)` in `GetContextMenu()` and `BuildContextMenu()`.
- Automation IDs are set on the `ContextMenu` (`"HamburgerMenu"`) and each `MenuItem` (`"MenuItem_{ItemName}"`, with spaces removed).
- `MenuItemPressed` is invoked with the `Header` string of the selected `MenuItem`.
---
### 4. **Dependencies**
**Imports/References (from source):**
- `System.ComponentModel`, `System.ComponentModel.Composition` (MEF)
- `Prism.Events`, `Prism.Regions` (Prism framework)
- `Unity` (Unity DI container)
- `DTS.Common.Events` (custom event types: `RaiseNotification`, `BusyIndicatorChangeNotification`, `TestEvent`)
- `DTS.Common.Interface.Menu.HamburgerMenu` (interface `IHamburgerMenuViewModel`)
- `DTS.Common.Interactivity` (interaction request types: `Notification`, `Confirmation`)
- `System.Windows.Controls`, `System.Windows.Automation`
**Depends on:**
- `IHamburgerMenuView` (view interface)
- `IRegionManager`, `IEventAggregator`, `IUnityContainer` (Prism/Unity infrastructure)
- `TestEvent`, `BusyIndicatorChangeNotification`, `RaiseNotification` (custom events via `IEventAggregator`)
**Used by:**
- Likely consumed by `IHamburgerMenuView` (WPF view) via data binding.
- Other modules may publish `TestEvent`, `BusyIndicatorChangeNotification`, or `RaiseNotification` to control its behavior.
---
### 5. **Gotchas**
- **Empty lifecycle methods**: `Initialize*`, `Cleanup*`, `Unset`, `OnSetActive`, and `Activated` are all no-ops. If lifecycle management is expected, this may be incomplete or deferred to the view.
- **`MenuItemPressed` is a delegate, not an event**: It is declared as `public MenuItemPressedDelegate MenuItemPressed { get; set; }`, meaning it can be overwritten and is not thread-safe for multicast subscriptions. Callers must ensure safe assignment.
- **`IsDirty` property exists but is never set**: Declared as `public bool IsDirty { get; private set; }`, but never assigned—likely unused or incomplete.
- **`IsMenuIncluded` and `IsNavigationIncluded` are never set internally**: Only exposed as properties; their values must be set externally (e.g., by view or another VM), but no logic uses them.
- **`AutomationProperties.AutomationIdProperty` is hardcoded**: Menu item IDs are derived by removing spaces from the header (`item.Replace(" ", "")`). This may cause collisions if headers differ only by whitespace (e.g., `"Run Test"` vs `"RunTest"` both become `"MenuItem_RunTest"`).
- **`GetContextMenu()` returns the same instance after first build**: Repeated calls return the cached `_contextMenu`. If `_menuItems` changes but `GetContextMenu()` is called before `SetMenuItems()`/`ClearMenuItems()` triggers `BuildContextMenu()`, stale items may be returned.
- **`OnTestEvent()` toggles `IsEnabled` only on `TestStarted`/`TestEnded`**: If `TestEventArg.Status` is anything else (e.g., `TestRunning`), `IsEnabled` remains unchanged—assumes only two statuses.
- **Thread safety**: Only `GetContextMenu()` and `BuildContextMenu()` are thread-safe. Other property setters (e.g., `IsBusy`) assume caller handles thread affinity (though `IsBusy` setter uses `OnPropertyChanged`, which may marshal to UI thread depending on binding context—*not guaranteed*).
- **No unsubscription from events**: The constructor subscribes to events but there is no `IDisposable` implementation or `Unsubscribe()` call—potential memory leak if the VM outlives its intended lifetime.
> *None of the above are necessarily bugs, but they are non-obvious and require awareness during maintenance or extension.*