This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1,139 @@
---
source_files:
- DTS Viewer/DTS.Viewer/Modules/Main/View/MainView.xaml.cs
- DTS Viewer/DTS.Viewer/Modules/Main/View/ViewerShellView.xaml.cs
- DTS Viewer/DTS.Viewer/Modules/Main/View/MainViewLite.xaml.cs
- DTS Viewer/DTS.Viewer/Modules/Main/View/ExportMainView.xaml.cs
- DTS Viewer/DTS.Viewer/Modules/Main/View/ViewerMainView.xaml.cs
- DTS Viewer/DTS.Viewer/Modules/Main/View/ExportMainViewGrid.xaml.cs
- DTS Viewer/DTS.Viewer/Modules/Main/View/ViewerMainViewGrid.xaml.cs
generated_at: "2026-04-16T11:26:12.276849+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "a7a3a3c725d7b68b"
---
# DTS Viewer Main Views Documentation
## 1. Purpose
This module contains the WPF view code-behind files for the main window and viewer components of the DTS Viewer application. It provides multiple view variants (standard, lite, export, and viewer modes) that implement a view-first MVVM architecture using Prism. The views handle UI initialization, event subscription for graph loading notifications, and PDF/image export functionality. These views serve as the visual containers for the application's primary user interface elements.
---
## 2. Public Interface
### MainView
```csharp
public partial class MainView : IMainView
```
- **Constructor**: `MainView()` - Initializes the WPF component via `InitializeComponent()`.
- Implements `IMainView` interface from `DTS.Common.Interface`.
### ViewerShellView
```csharp
public partial class ViewerShellView : IViewerShellView
```
- **Constructor**: `ViewerShellView()` - Initializes the WPF component via `InitializeComponent()`.
- Implements `IViewerShellView` interface from `DTS.Common.Interface`.
### MainViewLite
```csharp
public partial class MainViewLite : IMainViewerView
```
- **Constructor**: `MainViewLite()` - Initializes the WPF component via `InitializeComponent()`.
- Implements `IMainViewerView` interface from `DTS.Common.Interface`.
### ExportMainView
```csharp
public partial class ExportMainView : IExportMainView
```
- **Constructor**: `ExportMainView()` - Initializes the WPF component via `InitializeComponent()`.
- Implements `IExportMainView` interface from `DTS.Common.Interface`.
### ViewerMainView
```csharp
public partial class ViewerMainView : IViewerMainView
```
- **Constructor**: `ViewerMainView()` - Initializes the WPF component via `InitializeComponent()`.
- Implements `IViewerMainView` interface from `DTS.Common.Interface`.
- Contains commented-out code for AvalonDock layout serialization/deserialization (referencing `DockManager`, `XmlLayoutSerializer`, and `DataProViewerAvalonDock.config`).
### ExportMainViewGrid
```csharp
public partial class ExportMainViewGrid : IExportMainViewGrid
```
- **Constructor**: `ExportMainViewGrid()` - Initializes component and subscribes to `Loaded` event.
- Implements `IExportMainViewGrid` interface from `DTS.Common.Interface`.
- **Public Method**: `int SaveToPDF(string directory, string pdfFileName)` - Renders the view to PDF and PNG files. Returns `> 0` on success, `< 0` on failure, or `0` if `MainShell` is not yet rendered.
- **Private Property**: `IEventAggregator _eventAggregator` - Resolved from container on load.
- **Private Method**: `void SetFocus()` - Empty implementation (no operation).
- **Private Method**: `void ExportMainViewGrid_Loaded(object sender, RoutedEventArgs e)` - Resolves `IEventAggregator` and subscribes to `GraphLoadedCountNotification`.
- **Private Method**: `void OnGraphLoadedCountNotification(GraphLoadedCountNotificationArg arg)` - Delays 3 seconds then invokes `SetFocus` via dispatcher.
### ViewerMainViewGrid
```csharp
public partial class ViewerMainViewGrid : IViewerMainViewGrid
```
- **Constructor**: `ViewerMainViewGrid()` - Initializes component and subscribes to `Loaded` event.
- Implements `IViewerMainViewGrid` interface from `DTS.Common.Interface`.
- **Public Method**: `int SaveToPDF(string directory, string pdfFileName)` - Renders the view to PDF and PNG files. Returns `> 0` on success, `< 0` on failure, or `0` if `MainShell` is not yet rendered.
- **Private Property**: `IEventAggregator _eventAggregator` - Resolved from container on load.
- **Private Method**: `void SetFocus()` - Selects and focuses `chartOptTab` element.
- **Private Method**: `void ViewerMainViewGrid_Loaded(object sender, RoutedEventArgs e)` - Resolves `IEventAggregator` and subscribes to `GraphLoadedCountNotification`.
- **Private Method**: `void OnGraphLoadedCountNotification(GraphLoadedCountNotificationArg arg)` - Validates `DataContext` matches `arg.ParentVM`, delays 3 seconds, then invokes `SetFocus` via dispatcher.
---
## 3. Invariants
- All views must call `InitializeComponent()` in their constructor (WPF code-behind requirement).
- `SaveToPDF` requires `pdfFileName` to end with `.pdf` extension; otherwise returns `-1`.
- `SaveToPDF` requires both `directory` and `pdfFileName` to be non-null and non-empty; otherwise returns `-1`.
- `SaveToPDF` returns `0` if `MainShell.DesiredSize.Height` or `MainShell.DesiredSize.Width` is `0` (control not yet rendered).
- `OnGraphLoadedCountNotification` only processes the event if `DataContext` is non-null and matches `arg.ParentVM` (cast to `IBaseViewModel`).
- Event subscription to `GraphLoadedCountNotification` occurs only after the `Loaded` event fires (ensures `IEventAggregator` is available).
- PDF export renders at 300 DPI resolution.
- PNG export is generated alongside PDF with `.pdf` extension replaced by `.png`.
---
## 4. Dependencies
### External Dependencies
- **Prism.Events** - `IEventAggregator` for pub/sub event messaging.
- **Prism.Ioc** - `ContainerLocator` for service location.
- **C1.WPF.Pdf** - `C1PdfDocument` for PDF generation (ComponentOne library).
- **System.Windows** - WPF core types (`RoutedEventArgs`, `Visual`, `Dispatcher`, etc.).
- **System.Windows.Media** - `RenderTargetBitmap`, `WriteableBitmap`, `PixelFormats`, `VisualTreeHelper`.
- **System.Windows.Media.Imaging** - Bitmap rendering types.
### Internal Dependencies
- **DTS.Common.Interface** - Interface definitions (`IMainView`, `IViewerShellView`, `IMainViewerView`, `IExportMainView`, `IViewerMainView`, `IExportMainViewGrid`, `IViewerMainViewGrid`).
- **DTS.Common.Base** - `IBaseViewModel` base interface.
- **DTS.Common.Events** - `GraphLoadedCountNotification` event and `GraphLoadedCountNotificationArg` argument class.
- **DTS.Common.Utilities.Logging** - `APILogger.LogException(Exception)` for error logging.
- **DTS.Common.Utils.PNGImageUtil** - `SaveImage(FrameworkElement, string)` static method for PNG export.
### Consumers
- Unknown from source alone. These views are likely instantiated by a Prism bootstrapper or module initialization logic.
---
## 5. Gotchas
1. **Hardcoded 3-second delay**: Both `ExportMainViewGrid` and `ViewerMainViewGrid` use `Thread.Sleep(TimeSpan.FromSeconds(3))` before setting focus. This is a magic number with no configuration, potentially causing timing issues on slower systems.
2. **Empty SetFocus in ExportMainViewGrid**: The `SetFocus()` method in `ExportMainViewGrid` is empty, making the 3-second delayed focus operation a no-op. This may be intentional or dead code.
3. **Commented-out AvalonDock code**: `ViewerMainView` contains significant commented-out code for layout serialization using `XmlLayoutSerializer` and a `DockManager` element. This suggests either incomplete feature implementation or removed functionality that wasn't cleaned up.
4. **Multiple ReSharper disable directives**: `ExportMainView`, `ViewerMainView`, `ExportMainViewGrid`, and `ViewerMainViewGrid` all suppress multiple ReSharper inspections, which may mask potential code quality issues.
5. **Namespace inconsistency**: All files declare namespace `DTS.Viewer` despite residing in different subdirectories (e.g., `Modules/Main/View/`). This is intentional but may cause confusion when locating files.
6. **Event subscription without unsubscription**: Neither `ExportMainViewGrid` nor `ViewerMainViewGrid` unsubscribe from `GraphLoadedCountNotification`. This could cause memory leaks if views are created/destroyed frequently.
7. **PDF return value semantics**: The `SaveToPDF` method uses a tri-state return value (`>0`, `0`, `<0`) which is documented but unconventional. Callers must check for `> 0` rather than a simple boolean.
8. **Silent exception handling**: `SaveToPDF` catches all exceptions, logs them via `APILogger.LogException`, and returns `-1`. The caller receives no exception details.

View File

@@ -0,0 +1,271 @@
---
source_files:
- DTS Viewer/DTS.Viewer/Modules/Main/ViewModel/ViewerShellViewModel.cs
- DTS Viewer/DTS.Viewer/Modules/Main/ViewModel/MainViewModel.cs
- DTS Viewer/DTS.Viewer/Modules/Main/ViewModel/ExportMainViewModel.cs
generated_at: "2026-04-16T11:26:44.035903+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "ab73d8a45f8ea2f6"
---
# DTS Viewer Main Module ViewModels Documentation
## 1. Purpose
This module contains the core ViewModel classes for the DTS Viewer application's main shell and primary views. It implements the MVVM pattern using Microsoft Prism and Unity IoC container. The module orchestrates region management, event aggregation for cross-component communication, and view composition for the main application shell, standard viewer mode, and export-focused mode. The ViewModels serve as the presentation logic layer, binding views to data, handling user interactions via commands, and coordinating child view instantiation within named UI regions.
---
## 2. Public Interface
### ViewerShellViewModel
**Location:** `DTS.Viewer.Modules.Main.ViewModel`
**Class Declaration:**
```csharp
[Export(typeof(IShellView))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class ViewerShellViewModel : NotificationObject, IViewerShellViewModel
```
**Constructor:**
```csharp
public ViewerShellViewModel(IViewerShellView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
```
Initializes the shell view model, sets the View's DataContext, creates interaction requests, subscribes to `RaiseNotification` events, and registers `IMainView`/`MainView` and `IMainViewModel`/`MainViewModel` with the Unity container.
**Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `View` | `IViewerShellView` | Gets the associated shell view |
| `NotificationRequest` | `InteractionRequest<Notification>` | Interaction request for notification dialogs |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | Interaction request for confirmation dialogs |
| `ContextMainRegion` | `Object` | Gets/sets the content of the MainRegion |
| `IsMenuIncluded` | `bool` | Indicates whether menu is included |
| `IsNavigationIncluded` | `bool` | Indicates whether navigation is included |
| `HeaderInfo` | `string` | Returns `"MainRegion"` |
| `IsBusy` | `bool` | **Throws `NotImplementedException`** |
| `IsDirty` | `bool` | **Throws `NotImplementedException`** |
**Methods:**
| Method | Signature | Description |
|--------|-----------|-------------|
| `Initialize` | `void Initialize()` | Stub implementation (sets local `i = 10`) |
| `Initialize` | `void Initialize(object parameter)` | Stub implementation (sets local `i = 22`) |
| `Initialize` | `void Initialize(object parameter, object model)` | Empty stub |
| `Activated` | `void Activated()` | Empty stub |
| `Cleanup` | `void Cleanup()` | **Throws `NotImplementedException`** |
| `CleanupAsync` | `Task CleanupAsync()` | **Throws `NotImplementedException`** |
| `InitializeAsync` | `Task InitializeAsync()` | **Throws `NotImplementedException`** |
| `InitializeAsync` | `Task InitializeAsync(object parameter)` | **Throws `NotImplementedException`** |
| `GetRegions` | `List<FrameworkElement> GetRegions()` | Returns all elements named "Region" in the MainShell |
| `OnRaiseNotification` | `void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)` | Private handler that raises `NotificationRequest` with transformed args |
---
### MainViewModel
**Location:** `DTS.Viewer.Modules.Main.ViewModel`
**Class Declaration:**
```csharp
public class MainViewModel : BaseViewModel<IMainViewModel>, IMainViewModel
```
**Constructor:**
```csharp
public MainViewModel(IMainView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
```
Initializes the view model, sets DataContext, creates interaction requests, and subscribes to `RaiseNotification` event.
**Methods:**
| Method | Signature | Description |
|--------|-----------|-------------|
| `Initialize` | `override void Initialize()` | Empty override |
| `Initialize` | `override void Initialize(object parameter)` | Sets `Parent`, propagates menu/navigation flags, subscribes to `AssemblyListNotification` and `BusyIndicatorChangeNotification` events |
| `Activated` | `override void Activated()` | Empty override |
| `GetRegions` | `List<FrameworkElement> GetRegions()` | Returns all elements named "Region" in MainShell |
**Private Methods:**
| Method | Description |
|--------|-------------|
| `OnAssemblyListChange(AssemblyListInfo e)` | Processes assembly custom attributes ending with "ImageAttribute", creates `AssemblyNameImage` objects, and populates regions based on `eAssemblyRegion` enum |
| `OnRaiseNotification(NotificationContentEventArgs)` | Raises `NotificationRequest` with transformed content |
| `OnBusyIndicatorNotification(bool eventArg)` | Sets `IsBusy` property |
| `GetNavigationView(IBaseViewModel)` | Resolves and initializes `INavigationView`/`INavigationViewModel` |
| `GetPropertyView(IBaseWindowModel)` | Resolves and initializes `IPropertyView`/`IPropertyViewModel` |
| `GetGraphView(IBaseWindowModel)` | Resolves and initializes `IGraphView`/`IGraphViewModel` |
**Region Context Properties:**
| Property | Region Name |
|----------|-------------|
| `ContextNavigationRegion` | NavigationRegion |
| `ContextGraphRegion` | GraphRegion |
| `ContextTestsRegion` | TestsRegion |
| `ContextGraphsRegion` | GraphsRegion |
| `ContextLegendRegion` | LegendRegion |
| `ContextDiagRegion` | DiagRegion |
| `ContextStatsRegion` | StatsRegion |
| `ContextCursorRegion` | CursorRegion |
| `ContextPropertyRegion` | PropertyRegion |
**Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `View` | `IBaseView` | The associated view |
| `IsBusy` | `bool` | Busy indicator state |
| `IsBusyMessage` | `string` | Message for busy indicator |
| `IsMenuIncluded` | `bool` | Menu inclusion flag |
| `IsNavigationIncluded` | `bool` | Navigation inclusion flag |
| `HeaderInfo` | `string` | Returns `"MainRegion"` |
---
### ExportMainViewModel
**Location:** `DTS.Viewer.Modules.Main.ViewModel`
**Class Declaration:**
```csharp
public class ExportMainViewModel : BaseViewModel<IExportMainViewModel>, IExportMainViewModel
```
**Constructor:**
```csharp
public ExportMainViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
```
Initializes interaction requests, resolves `IExportMainViewGrid` as the View, and sets DataContext.
**Key Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `View` | `IBaseView` | Gets/sets the view (resolved as `IExportMainViewGrid`) |
| `Standalone` | `bool` | Determines whether to use `ExportMainView` or `ExportMainViewGrid` |
| `SelectedTest` | `string` | Currently selected test |
| `SelectedDTSFile` | `string` | Currently selected DTS file |
| `SelectedEventList` | `List<ITestEvent>` | List of selected test events |
| `AvailableTestIds` | `List<string>` | Available test IDs |
| `SettingsVisibility` | `Visibility` | Controls settings panel visibility |
| `ActiveContent` | `IBaseViewModel` | Currently active content |
| `TotalSelectedTests` | `int` | Count of selected tests |
| `TotalLoadedTests` | `int` | Count of loaded tests |
| `TotalSelectedGraphs` | `int` | Count of selected graphs |
| `TotalLoadedGraphs` | `int` | Count of loaded graphs |
| `SelectedDataFolder` | `string` | Selected data folder path |
| `SelectedDataFile` | `string` | Selected data file |
| `ShowModifications` | `bool` | Indicates if modifications should be shown |
| `ChannelCodeViewMode` | `IsoViewMode` | Channel code display mode (default: `IsoViewMode.ISOAndUserCode`) |
| `CalibrationBehaviorSetting` | `CalibrationBehaviors` | Calibration behavior (default: `CalibrationBehaviors.NonLinearIfAvailable`) |
| `CalibrationBehaviorSettableInViewer` | `bool` | Whether calibration behavior is settable (default: `true`) |
| `DoesUserHaveEditPermission` | `bool` | User edit permission flag (default: `false`) |
| `ConfigPath` | `string` | Configuration path |
| `IsBusy` | `bool` | Busy indicator state |
| `IsBusyMessage` | `string` | Busy indicator message |
| `IsMenuIncluded` | `bool` | Menu inclusion flag |
| `IsNavigationIncluded` | `bool` | Navigation inclusion flag |
| `HeaderInfo` | `string` | Returns `"MainRegion"` |
**Commands:**
| Command | CanExecute Condition | Action |
|---------|---------------------|--------|
| `LoadLayoutCommand` | `File.Exists(@".\DataProViewerAvalonDock.config")` | Deserializes AvalonDock layout from config file |
| `SaveLayoutCommand` | Always `true` | Serializes AvalonDock layout to `.\AvalonDock.config` |
**Public Methods:**
| Method | Signature | Description |
|--------|-----------|-------------|
| `Initialize` | `override void Initialize()` | Calls `Subscribe()` to register event handlers |
| `Initialize` | `override void Initialize(object parameter)` | Sets `Parent`, propagates flags, calls `Subscribe()` |
| `Activated` | `override void Activated()` | Empty override |
| `AddSelectedEvents` | `void AddSelectedEvents(string groupName, List<ITestEvent> events)` | Adds events to `SelectedEventList`, publishes busy indicator events |
| `SelectAndIncludeDataFile` | `void SelectAndIncludeDataFile(string value)` | Sets selected data file and publishes `DataFolderChangedEvent` |
| `ZoomReset` | `void ZoomReset()` | Publishes `ResetZoomChangedEvent` with `true` |
| `LeftKeyPress` | `void LeftKeyPress()` | Publishes `ShiftT0Event` with `-1` step |
| `RightKeyPress` | `void RightKeyPress()` | Publishes `ShiftT0Event` with `+1` step |
| `GetRegions` | `List<FrameworkElement> GetRegions()` | Returns regions based on `Standalone` mode |
**Private Event Handlers:**
| Method | Event Subscribed |
|--------|-----------------|
| `OnDataFileSelected` | `DataFileSelectedEvent` |
| `OnViewerSettingsVisibilityChanged` | `ViewerSettingsVisibilityChangedEvent` |
| `OnGraphLoadedCountChanged` | `GraphLoadedCountNotification` |
| `OnGraphSelectedCountChanged` | `GraphSelectedEventCountNotification` |
| `OnGraphChannelsReadCompleted` | `GraphChannelsReadCompletedNotification` (UIThread) |
| `OnTestLoadedChanged` | `TestLoadedCountNotification` |
| `OnTestSelectedCountChanged` | `TestSummaryCountNotification` |
| `OnLoadExportModule` | `LoadExportModuleEvent` |
| `OnShiftT0Event` | `ShiftT0Event` |
| `OnSaveToPDFRequested` | `SaveToPDFRequestedEvent` |
**View Factory Methods:**
| Method | Returns |
|--------|---------|
| `GetGraphView(IBaseViewModel)` | `IGraphView` with initialized `IGraphViewModel` |
| `GetGraphListView(IBaseViewModel)` | `IExportGraphMainView` with initialized `IExportGraphMainViewModel` |
| `GetTestDefinitionView(IBaseViewModel)` | `ITestSummaryListView` with initialized `ITestSummaryListViewModel` |
---
## 3. Invariants
1. **View-ViewModel Binding**: Each ViewModel sets `View.DataContext = this` in its constructor, establishing the binding invariant.
2. **Region Content Access**: All `ContextXxxRegion` properties cast the `View` to a concrete type (`MainView`, `ViewerShellView`, `ExportMainView`, or `ExportMainViewGrid`) before accessing region content. The view must be of the expected type.
3. **Parent Parameter Type**: In `MainViewModel.Initialize(object parameter)` and `ExportMainViewModel.Initialize(object parameter)`, the parameter is cast to `IBaseWindowModel` without type checking.
4. **Standalone Mode Switching**: `ExportMainViewModel` requires `Standalone` to be set correctly before accessing region properties, as it determines whether to cast to `ExportMainView` or `ExportMainViewGrid`.
5. **Event Subscription Pattern**: ViewModels subscribe to events in constructors or `Initialize` methods; unsubscribing is not visible in the source.
6. **Property Change Notification**: All setters that modify bound properties call `OnPropertyChanged(string)` with the property name.
7. **Unity Container Registration**: `ViewerShellViewModel` registers `IMainViewModel` with `ContainerControlledLifetimeManager`, making it a singleton.
---
## 4. Dependencies
### External Dependencies (from imports):
- `Microsoft.Practices.Prism.Events` - `IEventAggregator`, `ThreadOption`
- `Microsoft.Practices.Prism.Interactivity.InteractionRequest` - `InteractionRequest<T>`, `Notification`, `Confirmation`
- `Microsoft.Practices.Prism.Regions` - `IRegionManager`
- `Microsoft.Practices.Prism.ViewModel` - `NotificationObject`
- `Microsoft.Practices.Unity` - `IUnityContainer`, `ContainerControlledLifetimeManager`
- `System.ComponentModel.Composition` - `[Export]`, `[PartCreationPolicy]`, `CreationPolicy`
- `Xceed.Wpf.AvalonDock.Layout.Serialization` - `XmlLayoutSerializer` (ExportMainViewModel only)
- `Prism.Events` - Used in ExportMainViewModel alongside older Prism namespace
- `Prism.Regions` - Used in ExportMainViewModel alongside older Prism namespace
- `Unity` - Used in ExportMainViewModel alongside older Unity namespace
### Internal Dependencies:
- `DTS.Common.Base` - `BaseViewModel<T>`, `IBaseViewModel`, `IBaseView`, `IBaseWindowModel`
- `DTS.Common.Events` - Event types: `RaiseNotification`, `AssemblyListNotification`, `BusyIndicatorChangeNotification`, `DataFolderChangedEvent`, `LoadExportModuleEvent`, `TestLoadedCountNotification`, `TestSummaryCountNotification`, `GraphLoadedCountNotification`, `ShiftT0Event`, `GraphSelectedEventCountNotification`, `GraphChannelsReadCompletedNotification`, `ViewerSettingsVisibilityChangedEvent`, `DataFileSelectedEvent`, `SaveToPDFRequestedEvent`, `ChannelCodesViewChangedEvent`, `ExportCalibrationBehaviorSettingChangedEvent`, `CalibrationBehaviorSettableInViewerChangedEvent`, `ResetZoomChangedEvent`, `PageErrorEvent`
- `DTS.Common.Interface` - Various view/viewmodel interfaces: `IMainView`, `IMainViewModel`, `IViewerShellView`, `IViewerShellViewModel`, `INavigationView`, `INavigationViewModel`, `IPropertyView`, `IPropertyViewModel`, `IGraphView`, `IGraphViewModel`, `IExportMainViewGrid`, `IExportMainViewModel`, `IExportGraphMainView`, `IExportGraphMainViewModel`, `ITestSummaryListView`, `ITestSummaryListViewModel`, `ITestEvent`
- `DTS.Common.Utils` - `Utils.GetChildrenByName()`
- `DTS.Common.Enums` - `eAssemblyRegion`
- `DTS.Common.Enums.Sensors` - `IsoViewMode`, `CalibrationBehaviors`
- `DTS.Common.Classes.Viewer.Commands` - `RelayCommand`
- `DTS.Common.Interactivity` - (imported but usage unclear)
- `DTS.Viewer.Resources` - `StringResources`
### View Dependencies (referenced but not provided):
- `ViewerShellView`, `MainView`, `ExportMainView`, `ExportMainViewGrid`
---
## 5. Gotchas
1. **NotImplementedException Throwing Members**: `ViewerShellViewModel` has multiple members that throw `NotImplementedException`:
- `IsBusy` getter
- `IsDirty` getter
- `Cleanup()`
- `CleanupAsync()`
- `InitializeAsync()`
- `InitializeAsync(object parameter)`
These appear to be interface implementations that were never completed. Calling code must avoid these.
2. **Unused Local Variables**: `ViewerShellViewModel.Initialize()` methods set local `int i` variables that are never used—likely debug stubs.
3. **Duplicate DataContext Assignment**: `ExportMainViewModel` constructor sets `View.DataContext = this` twice