7.8 KiB
source_files, generated_at, model, schema_version, sha256
| source_files | generated_at | model | schema_version | sha256 | |
|---|---|---|---|---|---|
|
2026-04-16T04:48:30.206063+00:00 | Qwen/Qwen3-Coder-Next-FP8 | 1 | 462d2b26bf58cd93 |
ViewModel
Documentation: HamburgerMenuViewModel
1. Purpose
The HamburgerMenuViewModel class serves as the MVVM-compliant view model for the application’s 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 Prism’s 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 bindDataContext. -
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;
StandardINotifyPropertyChangedimplementation for data binding. -
void OnPropertyChanged(string propertyName);
Raises thePropertyChangedevent for the specified property. -
ContextMenu GetContextMenu();
Returns the lazily-builtContextMenuinstance. Builds it on first call if not already constructed. Thread-safe vialock(MyLock). -
void SetMenuItems(string[] items);
Sets the list of menu item labels and immediately rebuilds the context menu. -
void ClearMenuItems();
Clears the internal_menuItemsarray and triggers a rebuild (resulting in an empty menu). -
void EnableMenu(bool enable);
SetsIsEnabledtoenable, updating the UI state. -
void Unset();
Currently empty; no-op. -
void OnSetActive();
Currently empty; no-op. -
void Cleanup();
Currently empty; no-op. -
Task CleanupAsync();
ReturnsTask.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 returnTask.CompletedTask; no-op. -
void Activated();
Currently empty; no-op. -
bool IsEnabled { get; private set; }
Indicates whether the menu is enabled. Defaulttrue. Updated viaEnableMenu(),OnTestEvent(), or internal logic. -
bool IsBusy { get; set; }
Indicates whether the menu is in a busy state (e.g., during test execution). Bound toBusyIndicatorChangeNotificationevent. -
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). Theidpassed is theHeaderof the selectedMenuItem.
3. Invariants
View.DataContextis always set tothisin the constructor._contextMenuis lazily initialized on first call toGetContextMenu()and rebuilt only when_menuItemschanges (viaSetMenuItems()orClearMenuItems())._menuItemsis nevernull; it is initialized tonew string[0]and cleared tonew string[0].IsEnableddefaults totrue.IsBusyis updated synchronously on the publisher thread (viaThreadOption.PublisherThread) in response toBusyIndicatorChangeNotification.- Thread safety for context menu construction is ensured via
lock(MyLock)inGetContextMenu()andBuildContextMenu(). - Automation IDs are set on the
ContextMenu("HamburgerMenu") and eachMenuItem("MenuItem_{ItemName}", with spaces removed). MenuItemPressedis invoked with theHeaderstring of the selectedMenuItem.
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(interfaceIHamburgerMenuViewModel)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 viaIEventAggregator)
Used by:
- Likely consumed by
IHamburgerMenuView(WPF view) via data binding. - Other modules may publish
TestEvent,BusyIndicatorChangeNotification, orRaiseNotificationto control its behavior.
5. Gotchas
- Empty lifecycle methods:
Initialize*,Cleanup*,Unset,OnSetActive, andActivatedare all no-ops. If lifecycle management is expected, this may be incomplete or deferred to the view. MenuItemPressedis a delegate, not an event: It is declared aspublic MenuItemPressedDelegate MenuItemPressed { get; set; }, meaning it can be overwritten and is not thread-safe for multicast subscriptions. Callers must ensure safe assignment.IsDirtyproperty exists but is never set: Declared aspublic bool IsDirty { get; private set; }, but never assigned—likely unused or incomplete.IsMenuIncludedandIsNavigationIncludedare 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.AutomationIdPropertyis 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_menuItemschanges butGetContextMenu()is called beforeSetMenuItems()/ClearMenuItems()triggersBuildContextMenu(), stale items may be returned.OnTestEvent()togglesIsEnabledonly onTestStarted/TestEnded: IfTestEventArg.Statusis anything else (e.g.,TestRunning),IsEnabledremains unchanged—assumes only two statuses.- Thread safety: Only
GetContextMenu()andBuildContextMenu()are thread-safe. Other property setters (e.g.,IsBusy) assume caller handles thread affinity (thoughIsBusysetter usesOnPropertyChanged, 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
IDisposableimplementation orUnsubscribe()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.