Files
DP44/enriched-partialglm/DTS Viewer/DTS.Viewer/ViewModel.md
2026-04-17 14:55:32 -04:00

221 lines
16 KiB
Markdown

---
source_files:
- DTS Viewer/DTS.Viewer/ViewModel/NavigationViewModel.cs
- DTS Viewer/DTS.Viewer/ViewModel/MenuViewModel.cs
- DTS Viewer/DTS.Viewer/ViewModel/ShellViewModel.cs
- DTS Viewer/DTS.Viewer/ViewModel/ViewerShellViewModel.cs
- DTS Viewer/DTS.Viewer/ViewModel/MainViewModel.cs
generated_at: "2026-04-16T11:23:08.528119+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "7a17d7bd36c83744"
---
# DTS.Viewer ViewModel Documentation
## 1. Purpose
This module contains the core ViewModel layer for the DTS Viewer WPF application, implementing the MVVM pattern using Microsoft Prism and Unity. It provides the orchestration layer between the Views and the business logic, managing navigation regions, user notifications, and shell composition. The ViewModels handle view lifecycle (initialization, activation, cleanup), region management for dynamic view injection, and event-driven communication via `IEventAggregator`. This module serves as the structural backbone for the application's UI composition system.
---
## 2. Public Interface
### NavigationViewModel
**Inherits:** `BaseViewModel<INavigationViewModel>`
**Implements:** `INavigationViewModel`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `NavigationViewModel(INavigationView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)` | Initializes the view model, sets DataContext, creates interaction requests, and subscribes to `RaiseNotification` event. |
| NavigationView | `INavigationView { get; private set; }` | Holds reference to the associated view. |
| ContextNavigationRegion | `object { get; set; }` | Gets/sets the content of the `NavigationRegion` on the view. Raises `OnPropertyChanged("ContextNavigationRegion")` on set. |
| HeaderInfo | `string { get; }` | Returns hardcoded string `"NavigationRegion"`. |
| Initialize | `override void Initialize()` | Empty implementation. |
| Initialize | `override void Initialize(object parameter)` | Casts parameter to `IShellViewModel` and assigns to `Parent`. |
| OnRaiseNotification | `void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)` | Handles `RaiseNotification` events, transforms args and raises `NotificationRequest`. |
| IsBusy | `bool { get; set; }` | Throws `NotImplementedException`. |
| IsDirty | `bool { get; }` | Throws `NotImplementedException`. |
| Activated | `override void Activated()` | Throws `NotImplementedException`. |
| Cleanup | `override void Cleanup()` | Throws `NotImplementedException`. |
| CleanupAsync | `Task CleanupAsync()` | Throws `NotImplementedException`. |
| InitializeAsync | `override Task InitializeAsync()` | Throws `NotImplementedException`. |
| InitializeAsync | `override Task InitializeAsync(object parameter)` | Throws `NotImplementedException`. |
---
### MenuViewModel
**Inherits:** `BaseViewModel<IMenuViewModel>`
**Implements:** `IMenuViewModel`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `MenuViewModel(IMenuView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)` | Initializes the view model, sets DataContext, creates interaction requests, and subscribes to `RaiseNotification` event. |
| View | `IMenuView { get; private set; }` | Holds reference to the associated view. |
| HeaderInfo | `string { get; }` | Returns hardcoded string `"MainRegion"`. |
| Initialize | `override void Initialize()` | Contains placeholder code (`int i = 10;`). |
| Initialize | `override void Initialize(object parameter)` | Casts parameter to `IShellViewModel` and assigns to `Parent`. |
| CreateViews | `void CreateViews(Boolean initialize)` | Creates a `ViewDefinition` for `RegionNames.MainRegion` with `IBaseView`/`IBaseViewModel` types. Currently the `_regionManager.AddView` call is commented out. |
| OnRaiseNotification | `void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)` | Handles `RaiseNotification` events. |
| IsBusy | `bool { get; set; }` | Throws `NotImplementedException`. |
| IsDirty | `bool { get; }` | Throws `NotImplementedException`. |
| Activated | `override void Activated()` | Throws `NotImplementedException`. |
| Cleanup | `override void Cleanup()` | Throws `NotImplementedException`. |
| CleanupAsync | `Task CleanupAsync()` | Throws `NotImplementedException`. |
| InitializeAsync | `override Task InitializeAsync()` | Throws `NotImplementedException`. |
| InitializeAsync | `override Task InitializeAsync(object parameter)` | Throws `NotImplementedException`. |
---
### ShellViewModel
**Inherits:** `NotificationObject`
**Implements:** `IViewerShellViewModel`
**Attributes:** `[Export(typeof(IShellView))]`, `[PartCreationPolicy(CreationPolicy.Shared)]`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `ShellViewModel(IViewerShellView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)` | Initializes view, subscribes to `RaiseNotification`, registers `IMainView``MainView` and `IMainViewModel``MainViewModel` (singleton) with Unity. |
| View | `IViewerShellView { get; private set; }` | Holds reference to the shell view. |
| ContextMainRegion | `Object { get; set; }` | Gets/sets content of `MainRegion` from `ShellView`. Raises `OnPropertyChanged("ContextMainRegion")` on set. |
| IsMenuIncluded | `bool { get; set; }` | Controls menu visibility. Raises `OnPropertyChanged` on set. |
| IsNavigationIncluded | `bool { get; set; }` | Controls navigation visibility. Raises `OnPropertyChanged` on set. |
| HeaderInfo | `string { get; }` | Returns hardcoded string `"MainRegion"`. |
| GetRegions | `List<FrameworkElement> GetRegions()` | Uses `Utils.GetChildrenByName` to find elements named `"Region"` in `MainShell`. |
| Initialize | `void Initialize()` | Placeholder implementation (`int i = 10;`). |
| Initialize | `void Initialize(object parameter)` | Placeholder implementation (`int i = 22;`). |
| Initialize | `void Initialize(object parameter, object model)` | Empty implementation. |
| Activated | `void Activated()` | Placeholder (`var s = String.Empty;`). |
| OnRaiseNotification | `void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)` | Handles `RaiseNotification` events. |
| IsBusy | `bool { get; }` | Throws `NotImplementedException`. |
| IsDirty | `bool { get; }` | Throws `NotImplementedException`. |
| Cleanup | `void Cleanup()` | Throws `NotImplementedException`. |
| CleanupAsync | `Task CleanupAsync()` | Throws `NotImplementedException`. |
| InitializeAsync | `Task InitializeAsync()` | Throws `NotImplementedException`. |
| InitializeAsync | `Task InitializeAsync(object parameter)` | Throws `NotImplementedException`. |
---
### ViewerShellViewModel
**Inherits:** `NotificationObject`
**Implements:** `IViewerShellViewModel`
**Attributes:** `[Export(typeof(IShellView))]`, `[PartCreationPolicy(CreationPolicy.Shared)]`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `ViewerShellViewModel(IViewerShellView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)` | Initializes view, subscribes to `RaiseNotification`, registers `IViewerMainView``ViewerMainView` and `IViewerMainViewModel``ViewerMainViewModel` (singleton) with Unity. |
| View | `IViewerShellView { get; private set; }` | Holds reference to the shell view. |
| ContextMainRegion | `Object { get; set; }` | Gets/sets content of `MainRegion` from `ViewerShellView`. |
| IsMenuIncluded | `bool { get; set; }` | Controls menu visibility. |
| IsNavigationIncluded | `bool { get; set; }` | Controls navigation visibility. |
| IsBusy | `bool { get; set; }` | **Implemented** - unlike other ViewModels, this has a backing field `_isBusy` and raises property changed. |
| HeaderInfo | `string { get; }` | Returns hardcoded string `"MainRegion"`. |
| GetRegions | `List<FrameworkElement> GetRegions()` | Uses `Utils.GetChildrenByName` on `ViewerShellView.MainShell`. |
| Initialize | `void Initialize()` | Placeholder (`int i = 10;`). |
| Initialize | `void Initialize(object parameter)` | Placeholder (`int i = 22;`). |
| Initialize | `void Initialize(object parameter, object model)` | Empty implementation. |
| Activated | `void Activated()` | Placeholder (`var s = String.Empty;`). |
| OnRaiseNotification | `void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)` | Handles `RaiseNotification` events. |
| IsDirty | `bool { get; }` | Throws `NotImplementedException`. |
| Cleanup | `void Cleanup()` | Throws `NotImplementedException`. |
| CleanupAsync | `Task CleanupAsync()` | Throws `NotImplementedException`. |
| InitializeAsync | `Task InitializeAsync()` | Throws `NotImplementedException`. |
| InitializeAsync | `Task InitializeAsync(object parameter)` | Throws `NotImplementedException`. |
| OnPropertyChanged | `void IBasePropertyChanged.OnPropertyChanged(string propertyName)` | Throws `NotImplementedException`. |
---
### MainViewModel
**Inherits:** `BaseViewModel<IMainViewModel>`
**Implements:** `IMainViewModel`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `MainViewModel(IMainView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)` | Initializes view, subscribes to `RaiseNotification` and `AssemblyListNotification` events, registers `IMenuView`/`IMenuViewModel` and `INavigationView`/`INavigationViewModel` with Unity. |
| View | `IMainView { get; private set; }` | Holds reference to the main view. |
| ContextMainRegion | `object { get; set; }` | Currently returns `null` on get; setter raises `OnPropertyChanged("ContextMainRegion")` but content assignment is commented out. |
| IsMenuIncluded | `bool { get; set; }` | Backed by `_isMenuIncluded` field. |
| IsNavigationIncluded | `bool { get; set; }` | Backed by `_isNavigationIncluded` field. |
| HeaderInfo | `string { get; }` | Returns hardcoded string `"MainRegion"`. |
| Initialize | `override void Initialize()` | Empty implementation. |
| Initialize | `override void Initialize(object parameter)` | Casts to `IViewerShellViewModel`, sets `Parent.IsMenuIncluded` and `Parent.IsNavigationIncluded`, subscribes to `AssemblyListNotification` event with `ThreadOption.PublisherThread`. |
| Activated | `override void Activated()` | Empty implementation. |
| OnAssemblyListChange | `void OnAssemblyListChange(AssemblyListInfo e)` | Handler for `AssemblyListNotification` event. **Entire implementation is commented out.** |
| OnRaiseNotification | `void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)` | Handles `RaiseNotification` events. |
---
## 3. Invariants
1. **Constructor Pattern**: All ViewModels must receive exactly four constructor parameters: the view interface, `IRegionManager`, `IEventAggregator`, and `IUnityContainer`. The view's `DataContext` is set to `this` within the constructor.
2. **Event Subscription**: All ViewModels subscribe to `RaiseNotification` event via `EventAggregator.GetEvent<RaiseNotification>().Subscribe(OnRaiseNotification)` during construction.
3. **Notification Transformation**: The `OnRaiseNotification` handler always transforms `NotificationContentEventArgs` to a new instance with `(Message, MessageDetails, Image)` before raising the `NotificationRequest`.
4. **Parent Assignment**: The `Initialize(object parameter)` method expects `parameter` to be castable to either `IShellViewModel` (for `NavigationViewModel`, `MenuViewModel`) or `IViewerShellViewModel` (for `MainViewModel`).
5. **Region Naming Convention**: Region content properties follow the naming pattern `Context{RegionName}Region` (e.g., `ContextMainRegion`, `ContextNavigationRegion`).
6. **HeaderInfo Consistency**: All ViewModels return a hardcoded region name string from `HeaderInfo`.
---
## 4. Dependencies
### External Dependencies (Imports)
- `Microsoft.Practices.Prism.Events` - `IEventAggregator`, event publishing/subscription
- `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` - MEF attributes (`Export`, `PartCreationPolicy`, `CreationPolicy`)
- `System.Windows` - `FrameworkElement` (used in `GetRegions()`)
### Internal Dependencies (DTS.*)
- `DTS.Common.Base` - `BaseViewModel<T>`, `ViewDefinition`
- `DTS.Common.Events` - `RaiseNotification`, `NotificationContentEventArgs`, `AssemblyListNotification`, `AssemblyListInfo`
- `DTS.Common.Interface` - `INavigationViewModel`, `IMenuViewModel`, `IShellViewModel`, `IViewerShellViewModel`, `IMainViewModel`, `IBaseViewModel`, `IBaseView`, `IBasePropertyChanged`
- `DTS.Common.Utils` - `Utils.GetChildrenByName`
- `DTS.Common.Classes` - Referenced in `MenuViewModel`
- `DTS.Viewer.View` - `ShellView`, `ViewerShellView`, `MainView`, `MenuView`, `NavigationView`, `ViewerMainView`
### Dependency Graph
```
ShellViewModel / ViewerShellViewModel (root)
└── registers MainViewModel / ViewerMainViewModel
└── MainViewModel
└── registers MenuViewModel, NavigationViewModel
```
---
## 5. Gotchas
1. **Stale XML Documentation**: The XML comment in `NavigationViewModel` constructor references `"TechnologyDoFrontEditViewModel"` which does not match the actual class name. Similarly, `MenuViewModel` references `"TechnologyDomainEditViewModel"`. These appear to be copy-paste artifacts from another codebase.
2. **Widespread NotImplementedException**: The majority of lifecycle methods (`Activated`, `Cleanup`, `CleanupAsync`, `InitializeAsync`, `IsDirty` getter) throw `NotImplementedException` across all ViewModels. This indicates incomplete implementation—callers must not rely on these methods.
3. **Inconsistent IsBusy Implementation**:
- `ShellViewModel.IsBusy` throws `NotImplementedException`
- `ViewerShellViewModel.IsBusy` is fully implemented with backing field
- `NavigationViewModel.IsBusy` and `MenuViewModel.IsBusy` throw `NotImplementedException`
This inconsistency suggests `ViewerShellViewModel` is more complete than `ShellViewModel`.
4. **Commented-Out Critical Logic**:
- `MainViewModel.OnAssemblyListChange()` is entirely commented out—the method receives `AssemblyListInfo` but does nothing with it.
- `MainViewModel.ContextMainRegion` getter returns `null` and setter logic is commented out.
- `MenuViewModel.CreateViews()` has `_regionManager.AddView` call commented out.
5. **new Keyword Hiding**: Several members use `new` to hide base class members:
- `NavigationViewModel`: `PropertyChanged` event, `OnPropertyChanged` method, `IsBusy`, `IsDirty`, `CleanupAsync`
- `MenuViewModel`: `IsBusy`, `IsDirty`, `CleanupAsync`
- `MainViewModel`: `IsMenuIncluded`, `IsNavigationIncluded`
This may cause unexpected behavior when casting to base types.
6. **Placeholder Code**: Multiple `Initialize` methods contain placeholder statements like `int i = 10;` or `var s = String.Empty;` that serve no functional purpose—likely debug artifacts.
7. **Duplicate Shell Implementations**: Both `ShellViewModel` and `ViewerShellViewModel` implement `IViewerShellViewModel` and have nearly identical structure. The relationship between these two classes is unclear from source alone—they may represent different shell configurations or be a refactoring in progress.
8. **ThreadOption.PublisherThread in Event Subscription**: `