--- source_files: - DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReport/View/PSDReportMainView.xaml.cs - DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReport/View/PSDReportMainViewGrid.xaml.cs generated_at: "2026-04-16T11:03:50.028977+00:00" model: "zai-org/GLM-5-FP8" schema_version: 1 sha256: "7e23a726984c27b1" --- # Documentation: DTS.Viewer.PSDReport Views ## 1. Purpose This module provides WPF view components for the PSD (Power Spectral Density) Report feature within the DTS Viewer application. It contains two partial classes that serve as code-behind for XAML views: `PSDReportMainView` acts as a minimal container view, while `PSDReportMainViewGrid` manages tab focus behavior in response to graph loading events via Prism's event aggregation system. --- ## 2. Public Interface ### `PSDReportMainView` (class) **Implements:** `IPSDReportMainView` **Location:** `DTS.Viewer.PSDReport` namespace | Member | Signature | Description | |--------|-----------|-------------| | Constructor | `public PSDReportMainView()` | Initializes the XAML component. Contains commented-out code for AvalonDock layout serialization. | --- ### `PSDReportMainViewGrid` (class) **Implements:** `IPSDReportMainViewGrid` **Location:** `DTS.Viewer.PSDReport` namespace | Member | Signature | Description | |--------|-----------|-------------| | Constructor | `public PSDReportMainViewGrid()` | Initializes the XAML component and attaches a `Loaded` event handler. | | `_eventAggregator` | `private IEventAggregator` | Backing field for the Prism event aggregator, resolved at runtime. | | `SetFocus` | `private void SetFocus()` | Selects and focuses the `chartResultsTab` element. | | `PSDReportMainViewGrid_Loaded` | `private void PSDReportMainViewGrid_Loaded(object sender, RoutedEventArgs e)` | Resolves `IEventAggregator` from the container and subscribes to `GraphLoadedCountNotification` events. | | `OnGraphLoadedCountNotification` | `private void OnGraphLoadedCountNotification(GraphLoadedCountNotificationArg arg)` | Event handler that waits 3 seconds then sets focus to the chart results tab via `Dispatcher.BeginInvoke`. | --- ## 3. Invariants - **Container Availability:** `PSDReportMainViewGrid` requires `ContainerLocator.Container` to be properly initialized before the `Loaded` event fires, otherwise `_eventAggregator` will be null. - **DataContext Type:** The `DataContext` of `PSDReportMainViewGrid` must be castable to `IBaseViewModel` for the event filtering logic in `OnGraphLoadedCountNotification` to function correctly. - **XAML Element Existence:** The `chartResultsTab` element (referenced in `SetFocus()`) must be defined in the associated XAML file. - **Event Matching:** The `OnGraphLoadedCountNotification` handler only executes its focus logic when `arg.ParentVM` matches the view's `DataContext` (after casting to `IBaseViewModel`). --- ## 4. Dependencies ### This module depends on: - `DTS.Common.Interface` — Provides `IPSDReportMainView`, `IPSDReportMainViewGrid`, and `IBaseViewModel` - `DTS.Common.Base` — Referenced but specific types not visible in code-behind - `DTS.Common.Events` — Provides `GraphLoadedCountNotification` event and `GraphLoadedCountNotificationArg` - `Prism.Ioc` — Provides `ContainerLocator` for service resolution - `Prism.Events` — Provides `IEventAggregator` for pub/sub messaging - `System` — `Action` delegate - `System.Threading` — `Thread.Sleep` - `System.Threading.Tasks` — `Task.Run` ### What depends on this module: - Not determinable from the provided source files alone. Consumers would be modules that instantiate `IPSDReportMainView` or `IPSDReportMainViewGrid` (likely via dependency injection or navigation). --- ## 5. Gotchas 1. **Hardcoded 3-Second Delay:** The `OnGraphLoadedCountNotification` method uses `Thread.Sleep(TimeSpan.FromSeconds(3))` before setting focus. This is a magic number with no configuration or explanation—likely a workaround for timing issues with graph rendering completion. 2. **Commented-Out AvalonDock Code:** `PSDReportMainView` contains significant commented-out code for layout serialization using `XmlLayoutSerializer` and a file path `.\DataProViewerAvalonDock.config`. This suggests dock panel persistence was previously implemented but intentionally disabled. 3. **Late Event Subscription:** Per the comment "FB 14797", the event subscription occurs in the `Loaded` event handler rather than the constructor. This means any `GraphLoadedCountNotification` events fired before the view is fully loaded will be missed. 4. **Silent Failure on Container Resolution:** The `_eventAggregator?.GetEvent<...>()` call uses a null-conditional operator. If `ContainerLocator.Container.Resolve()` returns null, the subscription silently fails with no logging or error handling. 5. **Dispatcher Threading:** The focus operation is marshaled to the UI thread via `Dispatcher.BeginInvoke`, but the 3-second sleep runs on a background thread via `Task.Run`. This is intentional but could be a source of race conditions if the view is unloaded during the wait period.