--- source_files: - DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReportResults/ViewModel/PSDReportResultsViewModel.cs generated_at: "2026-04-16T11:01:33.528546+00:00" model: "zai-org/GLM-5-FP8" schema_version: 1 sha256: "7cb2cb6c499c73c1" --- # Documentation: PSDReportResultsViewModel ## 1. Purpose `PSDReportResultsViewModel` is a Prism-based view model responsible for displaying PSD (Power Spectral Density) report results, specifically GRMS (Root Mean Square) summary data for channels. It serves as a subscriber to report update events and provides user-initiated export functionality to PDF and CSV formats. The view model participates in a parent-child relationship with another view model (passed during initialization) and filters incoming events to ensure it only processes data intended for its specific context. --- ## 2. Public Interface ### Properties | Name | Type | Description | |------|------|-------------| | `View` | `IBaseView` | Gets or sets the associated view instance. Assigned in constructor. | | `Parent` | `IBaseViewModel` | Gets or sets the parent view model. Used to filter event subscriptions. Set during `Initialize`. | | `Results` | `ObservableCollection` | Collection of GRMS summary results displayed to the user. Cleared and repopulated on `PSDReportGRMSValuesUpdatedEvent`. | | `NotificationRequest` | `InteractionRequest` | Interaction request for showing notifications to the user. | | `ConfirmationRequest` | `InteractionRequest` | Interaction request for showing confirmation dialogs. Declared with `new` keyword (hides base member). | | `ExportToPDFCommand` | `DelegateCommand` | Command that triggers PDF export by publishing `SaveReportToPDFRequestedEvent`. Lazily instantiated. | | `ExportToCSVCommand` | `DelegateCommand` | Command that triggers CSV export by publishing `SaveReportToCSVRequestedEvent`. Lazily instantiated. | ### Methods | Signature | Description | |-----------|-------------| | `PSDReportResultsViewModel(IPSDReportSettingsView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)` | Constructor. Accepts an `IPSDReportSettingsView` (note: not `IPSDReportResultsView`), assigns it to `View`, sets `DataContext` to itself, and initializes interaction requests and service references. | | `override void Initialize(object parameter)` | Initializes the view model. Expects `parameter` to be castable to `IBaseViewModel` (assigned to `Parent`). Creates empty `Results` collection and subscribes to events. | --- ## 3. Invariants 1. **Parent-based event filtering**: Both `OnGRMSValuesUpdated` and `OnGraphSelectedChannelsChanged` check `if (Parent != arg.ParentVM) return;` — events are ignored if the sender's parent view model does not match this instance's parent. 2. **Results collection lifecycle**: `Results` is instantiated as an empty `ObservableCollection` in `Initialize`, not in the constructor. It is cleared before repopulation in `OnGRMSValuesUpdated`. 3. **Directory derivation**: The private `Directory` property is derived from the first selected channel's `BinaryFilePath` with `"Binary"` replaced by `"Reports"` via `ReplaceLast`. If no channels are selected, `Directory` is set to `string.Empty`. 4. **Lazy command instantiation**: Both `ExportToPDFCommand` and `ExportToCSVCommand` use lazy initialization via null-coalescing pattern. --- ## 4. Dependencies ### This module depends on: - **DTS.Common.Base** — `BaseViewModel` - **DTS.Common.Events** — `PSDReportGRMSValuesUpdatedEvent`, `PSDReportGRMSValuesUpdatedEventArg`, `GraphSelectedChannelsNotification`, `GraphSelectedChannelsNotificationArg`, `SaveReportToPDFRequestedEvent`, `SaveReportToPDFRequestedEventArgs`, `SaveReportToCSVRequestedEvent`, `SaveReportToCSVRequestedEventArgs` - **DTS.Common.Interactivity** — `InteractionRequest`, `Notification`, `Confirmation` - **DTS.Common.Interface** — `IBaseView`, `IBaseViewModel`, `IPSDReportResultsViewModel`, `IChannelGRMSSummary`, `ITestChannel`, `IPSDReportSettingsView` - **DTS.Common.Utils** — `ReplaceLast` extension method (inferred from usage on string) - **Prism.Delegates** — `DelegateCommand` - **Prism.Events** — `IEventAggregator`, `ThreadOption` - **Prism.Regions** — `IRegionManager` - **Unity** — `IUnityContainer` - **System.Collections.ObjectModel** — `ObservableCollection` ### What depends on this module: - Not determinable from this source file alone. Consumers would implement `IPSDReportResultsView` and resolve `IPSDReportResultsViewModel` via the container. --- ## 5. Gotchas 1. **Constructor parameter type mismatch**: The constructor accepts `IPSDReportSettingsView` but the class implements `IPSDReportResultsViewModel`. This appears inconsistent — the view type name suggests "settings" while the view model is for "results". This may be intentional coupling or a copy-paste error. 2. **Member hiding with `new` keyword**: - `_regionManager` is declared with `new`, hiding the base class's `_regionManager`. - `ConfirmationRequest` is declared with `new`, hiding a base class member. - This suggests the base class `BaseViewModel` already defines these members, and the derived class is overriding them shadow-style rather than using proper override/virtual patterns. 3. **Unused service references**: `_eventAggregator`, `_unityContainer`, and `_regionManager` are stored as private fields despite the base class constructor already receiving them. The `new` keyword on `_regionManager` indicates potential confusion about inheritance. 4. **Null-conditional handling inconsistency**: `OnGraphSelectedChannelsChanged` uses null-conditional operators (`arg?.ParentVM`, `arg?.SelectedChannels`) while `OnGRMSValuesUpdated` does not. This suggests different assumptions about event argument nullability. 5. **Unused imports**: `System.Threading.Tasks` is imported but no async/await or Task usage is present in the file.