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,129 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Loader/App.xaml.cs
- DTS Viewer/DTS.Viewer.Loader/MainWindow.xaml.cs
- DTS Viewer/DTS.Viewer.Loader/ViewerLoaderSession.cs
- DTS Viewer/DTS.Viewer.Loader/Bootstrapper.cs
generated_at: "2026-04-16T10:58:04.030267+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "d7175f2d8133b4b4"
---
# DTS.Viewer.Loader Module Documentation
## 1. Purpose
The `DTS.Viewer.Loader` module serves as the entry point and bootstrapping layer for a Prism-based WPF viewer application. Its primary role is to initialize the Unity dependency injection container, configure module discovery via directory-based cataloging, and orchestrate the startup of the main viewer session. This module acts as the composition root that wires together the shell view, region management, and dynamically loaded plugins.
---
## 2. Public Interface
### `App` (partial class, inherits `Application`)
**File:** `App.xaml.cs`
| Member | Signature | Description |
|--------|-----------|-------------|
| `App_OnStartup` | `private void App_OnStartup(object sender, StartupEventArgs e)` | Application startup event handler. Instantiates a `ViewerLoaderSession` and calls `CreateSession()` to initialize the application. |
---
### `MainWindow` (partial class, inherits `Window`)
**File:** `MainWindow.xaml.cs`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `public MainWindow()` | Calls `InitializeComponent()`. Standard WPF window initialization. |
---
### `ViewerLoaderSession`
**File:** `ViewerLoaderSession.cs`
| Member | Signature | Description |
|--------|-----------|-------------|
| `_unityContainer` | `public IUnityContainer _unityContainer { get; private set; }` | Exposes the Unity dependency injection container after session creation. |
| `ServiceLocator` | `public IServiceLocator ServiceLocator { get; private set; }` | Exposes the Prism service locator. |
| `EventAggregator` | `public IEventAggregator EventAggregator { get; private set; }` | Exposes the Prism event aggregator for pub/sub messaging. |
| `RegionManager` | `public IRegionManager RegionManager { get; private set; }` | Exposes the Prism region manager for view composition. |
| Constructor | `public ViewerLoaderSession()` | Default constructor. No initialization performed. |
| `CreateSession` | `public void CreateSession()` | Main initialization method. Creates the bootstrapper, resolves core services from the container, starts the viewer module, and sets the main region context on the shell viewmodel. |
| `Terminate` | `public void Terminate()` | Called during application shutdown. Currently empty implementation. |
| `GetRegisteredViewType` | `private Type GetRegisteredViewType(string name)` | Queries the Unity container registrations for a registered type matching the given name suffix. Returns the first match or default. |
| `LoadPlugins` | `private List<Assembly> LoadPlugins()` | Uses `PluginManager.GetPluginManager()` to load plugin assemblies implementing `IModule` from a configuration file path. |
---
### `Bootstrapper` (inherits `UnityBootstrapper`)
**File:** `Bootstrapper.cs`
| Member | Signature | Description |
|--------|-----------|-------------|
| `_serviceLocator` | `public IServiceLocator _serviceLocator { get; private set; }` | Exposes the resolved service locator instance. |
| `_EventAggregator` | `public IEventAggregator _EventAggregator { get; private set; }` | Exposes the resolved event aggregator instance. |
| `ConfigureContainer` | `protected override void ConfigureContainer()` | Registers `IShellView``ShellView` and `IShellViewModel``ShellViewModel` (singleton) with the Unity container, then calls base implementation. |
| `ConfigureRegionAdapterMappings` | `protected override RegionAdapterMappings ConfigureRegionAdapterMappings()` | Returns `null`. Region adapter configuration is intentionally disabled to avoid interfering with the viewer app's mappings. |
| `CreateShell` | `protected override DependencyObject CreateShell()` | Resolves the shell viewmodel, initializes it, attaches a closing event handler, and returns the `ShellView` instance. |
| `CreateModuleCatalog` | `protected override IModuleCatalog CreateModuleCatalog()` | Returns a new `AggregateModuleCatalog` instance for aggregating multiple module catalogs. |
| `ConfigureModuleCatalog` | `protected override void ConfigureModuleCatalog()` | Creates a `DirectoryModuleCatalog` using the plugin folder path from `Properties.Settings.Default.PluginFolder` and adds it to the aggregate catalog. |
| `InitializeModules` | `protected override void InitializeModules()` | Registers `IDTSRegionManager``DTSRegionManager` as a singleton, then calls base initialization. |
| `Bootstrapper_Closing` | `void Bootstrapper_Closing(object sender, CancelEventArgs e)` | Event handler for shell closing; calls `Application.Current.Shutdown(1)`. |
---
## 3. Invariants
1. **Bootstrapper Singleton Pattern**: The `_bootstrapper` field in `ViewerLoaderSession` must only be created once. The `CreateBootstrapper()` method checks for null before instantiation and throws if creation fails.
2. **Container Availability**: The `_unityContainer`, `ServiceLocator`, `EventAggregator`, and `RegionManager` properties on `ViewerLoaderSession` are only valid after `CreateSession()` has been successfully called and `_bootstrapper` is non-null.
3. **Shell ViewModel Lifetime**: `ShellViewModel` is registered with `ContainerControlledLifetimeManager`, making it a singleton within the container.
4. **Module Path Configuration**: The module catalog depends on `Properties.Settings.Default.PluginFolder` being correctly configured; otherwise, module discovery will fail.
5. **Region Adapter Mappings**: `ConfigureRegionAdapterMappings()` returns `null` by design—this is intentional to prevent interference with the viewer application's existing region adapters.
---
## 4. Dependencies
### External Dependencies (Imports)
| Namespace | Purpose |
|-----------|---------|
| `DTS.Common` | Common utilities and types |
| `DTS.Common.Base` | Base classes |
| `DTS.Common.Classes` | Common class implementations |
| `DTS.Common.Core.PluginLib` | Plugin management infrastructure (`PluginManager`, `IModule`) |
| `DTS.Common.Interface` | Core interfaces (`IShellView`, `IShellViewModel`, `IShellViewModel`, `IViewerModule`, `IViewerMainViewModel`, `IDTSRegionManager`) |
| `Microsoft.Practices.Prism.Events` | `IEventAggregator` for event aggregation |
| `Microsoft.Practices.Prism.Modularity` | `IModuleCatalog`, `DirectoryModuleCatalog`, `AggregateModuleCatalog` |
| `Microsoft.Practices.Prism.Regions` | `IRegionManager`, `RegionAdapterMappings` |
| `Microsoft.Practices.Prism.UnityExtensions` | `UnityBootstrapper` base class |
| `Microsoft.Practices.ServiceLocation` | `IServiceLocator` |
| `Microsoft.Practices.Unity` | `IUnityContainer`, `ContainerControlledLifetimeManager`, `InjectionMember` |
| `System.Windows` | WPF core types (`Application`, `Window`, `DependencyObject`, `Visibility`) |
### Internal Dependencies
- `ShellView` and `ShellViewModel` are resolved via Unity but their definitions are not included in the provided source files.
- `DTSRegionManager` is referenced but not defined in the provided source.
---
## 5. Gotchas
1. **Hardcoded Configuration Path**: In `ViewerLoaderSession.CreateSession()`, the path `@"C:\devDTS\RunTimeModules\DTS.Viewer.dll.config"` is hardcoded in the call to `viewerModule.StartSession()`. This will likely fail on machines without this specific directory structure.
2. **SynchronizationLockException Swallowed**: In `Bootstrapper.ConfigureContainer()`, the `System.Threading.SynchronizationLockException` is caught but has an empty catch block with no logging or handling. This may mask threading issues.
3. **Bootstrapper Cannot Be Re-created**: As documented in the remarks on `_bootstrapper`, once modules are loaded into the `DirectoryModuleCatalog`, module initializers will not be called again on subsequent bootstrapper creations. The bootstrapper loads approximately 40 MB into memory and cannot be fully unloaded without additional effort.
4. **Commented-Out Code Blocks**: `ViewerLoaderSession.CreateSession()` contains significant commented-out code related to plugin loading and view registration, suggesting incomplete refactoring or alternative implementation paths that were abandoned.
5. **Region Adapter Mappings Disabled**: The `ConfigureRegionAdapterMappings()` override returns `null` and has commented-out code for `StackPanelRegionAdapter`. This may cause issues if region adapters are expected by other modules.
6. **Application Shutdown Code**: The `Bootstrapper_Closing` handler calls `Application.Current.Shutdown(1)` with exit code 1, which typically indicates an error condition. This may be unintentional.
7. **Null Check After Creation**: `CreateBootstrapper()` has a redundant null check after the try-catch block—the exception handling re-throws, so if execution reaches the second null check, the bootstrapper should always be non-null unless there's a race condition.

View File

@@ -0,0 +1,74 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Loader/Properties/Settings.Designer.cs
- DTS Viewer/DTS.Viewer.Loader/Properties/AssemblyInfo.cs
- DTS Viewer/DTS.Viewer.Loader/Properties/Resources.Designer.cs
generated_at: "2026-04-16T11:27:08.948966+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "c2c4643ad51e5dc7"
---
# Documentation: DTS.Viewer.Loader Properties
## 1. Purpose
This module provides configuration and resource infrastructure for the `DTS.Viewer.Loader` assembly, a component developed by Diversified Technical Systems, Inc. The module exists to manage application-level settings—specifically the path to a plugin/modules folder—and to provide strongly-typed resource access for localization. It serves as the configuration layer for a plugin loading mechanism within the larger DTS Viewer application system.
---
## 2. Public Interface
### `Settings` class (partial, sealed)
**Namespace:** `DTS.Viewer.Loader.Properties`
**Base class:** `global::System.Configuration.ApplicationSettingsBase`
| Member | Signature | Description |
|--------|-----------|-------------|
| `Default` | `public static Settings Default { get; }` | Static property returning the singleton instance of `Settings`, synchronized for thread safety. |
| `PluginFolder` | `public string PluginFolder { get; }` | Application-scoped setting returning the relative path to the runtime modules directory. Default value: `"../../../../RunTimeModules"`. |
### `Resources` class (internal)
**Namespace:** `DTS.Viewer.Loader.Properties`
| Member | Signature | Description |
|--------|-----------|-------------|
| `ResourceManager` | `internal static global::System.Resources.ResourceManager ResourceManager { get; }` | Returns the cached `ResourceManager` instance for this assembly's resources. |
| `Culture` | `internal static global::System.Globalization.CultureInfo Culture { get; set; }` | Gets or sets the current thread's `CurrentUICulture` for resource lookups. |
---
## 3. Invariants
- **Singleton Pattern**: The `Settings` class maintains exactly one instance via `defaultInstance`, created through `ApplicationSettingsBase.Synchronized()`, ensuring thread-safe access.
- **Application-Scoped Immutability**: `PluginFolder` is decorated with `[ApplicationScopedSettingAttribute()]`, meaning it is read-only at runtime and cannot be modified programmatically—only through configuration file changes.
- **Auto-Generated Code**: Both `Settings` and `Resources` are designer-generated files; manual modifications will be overwritten upon regeneration.
- **Internal Visibility**: Both `Settings` and `Resources` classes are marked `internal sealed`, restricting access to within the `DTS.Viewer.Loader` assembly.
---
## 4. Dependencies
### This module depends on:
- `System.Configuration.ApplicationSettingsBase` — for application settings management
- `System.Resources.ResourceManager` — for resource lookup
- `System.Globalization.CultureInfo` — for culture-specific resource handling
- `System.Reflection` — for assembly metadata attributes
- `System.Runtime.CompilerServices` — for compiler-generated attributes
- `System.Runtime.InteropServices` — for COM visibility attributes
- `System.Windows` — for WPF `ThemeInfo` attribute
### What depends on this module:
- **Unclear from source alone.** The `Settings.Default.PluginFolder` property suggests consumers within the `DTS.Viewer.Loader` assembly use this to locate runtime modules/plugins, but the actual loader implementation is not present in these files.
---
## 5. Gotchas
1. **Relative Path Dependency**: The `PluginFolder` setting uses a relative path `"../../../../RunTimeModules"`. This path is relative to the application's working directory at runtime, not the assembly location. The actual resolved path will vary depending on how the application is launched.
2. **Auto-Generated Files**: Both `Settings.Designer.cs` and `Resources.Designer.cs` are tool-generated. Changes must be made through the corresponding `.settings` and `.resx` files in Visual Studio, not directly in these source files.
3. **Empty Resources**: The `Resources` class infrastructure exists but no actual string resources are defined in the provided source. The `ResourceManager` will look for a resource file named `"DTS.Viewer.Loader.Properties.Resources"`.
4. **Version Hardcoded**: Assembly version is fixed at `1.0.0.0` for both `AssemblyVersion` and `FileVersion`. Automatic versioning is commented out in the source.

View File

@@ -0,0 +1,58 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Loader/View/ShellView.xaml.cs
generated_at: "2026-04-16T11:27:08.367475+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "5592dd58a3630256"
---
# Documentation: ShellView.xaml.cs
## 1. Purpose
`ShellView` is the main shell window component for the DTS Viewer application. It serves as the primary container/view for the application's user interface, implementing the `IShellView` interface to integrate with the broader system architecture. The class handles window initialization and ensures the application launches in a maximized state.
## 2. Public Interface
### `ShellView` (class)
**Signature:**
```csharp
public partial class ShellView : IShellView
```
**Description:** A WPF window control that serves as the application's main shell. Implements `IShellView` from `DTS.Common.Interface`.
---
### `ShellView()` (constructor)
**Signature:**
```csharp
public ShellView()
```
**Description:** Default constructor that initializes the window component and sets the initial window state.
**Behavior:**
1. Calls `InitializeComponent()` to load the XAML-defined UI
2. Sets `this.WindowState = WindowState.Maximized` to launch the window in maximized mode
## 3. Invariants
- The window will always initialize in a maximized state (`WindowState.Maximized`).
- The class is a partial class, implying a companion XAML file (`ShellView.xaml`) must exist and define the visual tree.
- The class must implement `IShellView`, though the specific interface members are not visible in this source file.
## 4. Dependencies
### This module depends on:
- **`System.Windows`** - WPF framework for window management (`Window`, `WindowState`, `ResizeMode`)
- **`DTS.Common.Interface.IShellView`** - Interface contract this view implements
### What depends on this module:
- Cannot be determined from this source file alone. Likely consumed by a bootstrapper, main entry point, or an IoC container that resolves `IShellView`.
## 5. Gotchas
- **Commented-out `StateChanged` handler:** There is disabled code that would have toggled `ResizeMode` between `ResizeMode.NoResize` (when maximized) and `ResizeMode.CanResize` (otherwise). The reason for commenting this out is unclear from source alone—this may be intentional behavior removal or a pending fix.
- **No explicit interface implementation visible:** The source shows `IShellView` is implemented, but no interface members are explicitly defined in this file. They may be auto-implemented properties or defined in the XAML code-behind.

View File

@@ -0,0 +1,114 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Loader/ViewModel/ShellViewModel.cs
generated_at: "2026-04-16T11:26:51.573043+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "4117e2f039d6caa8"
---
# ShellViewModel Documentation
## 1. Purpose
`ShellViewModel` serves as the main shell ViewModel for the DTS Viewer application loader. It acts as the primary orchestration layer for the application's UI shell, managing region navigation, notification/confirmation dialogs, and coordinating between the view layer and the Prism infrastructure (EventAggregator, RegionManager, UnityContainer). This class is the entry point for the shell's UI composition pattern, exposing regions for dynamic view injection and handling cross-component communication via events.
---
## 2. Public Interface
### Constructor
```csharp
public ShellViewModel(IShellView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
```
Initializes the shell ViewModel, sets the View's DataContext to itself, creates interaction requests, and subscribes to the `RaiseNotification` event.
### Properties
| Property | Type | Description |
|----------|------|-------------|
| `View` | `IShellView` | The associated shell view instance. |
| `NotificationRequest` | `InteractionRequest<Notification>` | Interaction request for displaying notification dialogs. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | Interaction request for displaying confirmation dialogs. |
| `Width` | `double` | Gets or sets the shell width. |
| `Height` | `double` | Gets or sets the shell height. |
| `IsMenuIncluded` | `bool` | Gets or sets whether the menu is included; raises `PropertyChanged`. |
| `IsNavigationIncluded` | `bool` | Gets or sets whether navigation is included; raises `PropertyChanged`. |
| `HeaderInfo` | `string` | Returns the constant string `"MainRegion"`. |
| `IsBusy` | `bool` | Gets or sets the busy indicator state. |
| `IsDirty` | `bool` | Read-only; always returns `false` (no setter logic). |
| `ContextMainRegion` | `Object` | Gets or sets the content of the `MainRegion` on the View; raises `PropertyChanged` on set. |
### Methods
```csharp
public void Initialize()
public void Initialize(object parameter)
public void Activated()
```
Empty implementations. No behavior executed.
```csharp
public List<FrameworkElement> GetRegions()
```
Returns all FrameworkElements named "Region" within the `MainShell` of the `ShellView` by calling `Utils.GetChildrenByName`.
```csharp
public void Cleanup()
public Task CleanupAsync()
public Task InitializeAsync()
public Task InitializeAsync(object parameter)
```
All throw `NotImplementedException`.
### Events
```csharp
public event PropertyChangedEventHandler PropertyChanged
```
Standard `INotifyPropertyChanged` implementation. Raised via private `OnPropertyChanged(string propertyName)` method.
---
## 3. Invariants
1. **Singleton Scope**: The class is decorated with `[PartCreationPolicy(CreationPolicy.Shared)]`, ensuring a single shared instance per MEF container.
2. **DataContext Binding**: The View's `DataContext` is always set to the ViewModel instance during construction.
3. **Event Subscription**: The ViewModel subscribes to `RaiseNotification` event via `_eventAggregator.GetEvent<RaiseNotification>().Subscribe(OnRaiseNotification)` during construction.
4. **View Casting**: Methods `GetRegions()` and `ContextMainRegion` property assume the `View` can be cast to `ShellView` concrete type.
---
## 4. Dependencies
### This Module Depends On:
- `DTS.Common.Events``RaiseNotification` event type
- `DTS.Common.Interface``IShellView`, `IViewerShellView`, `IViewerShellViewModel` interfaces
- `DTS.Common.Utils``Utils.GetChildrenByName` static method
- `DTS.Common.Base` — (imported but usage unclear from source)
- `Microsoft.Practices.Prism.Events``IEventAggregator`
- `Microsoft.Practices.Prism.Interactivity.InteractionRequest``InteractionRequest<T>`, `Notification`, `Confirmation`
- `Microsoft.Practices.Prism.Regions``IRegionManager`
- `Microsoft.Practices.Prism.ViewModel` — (likely `NotificationObject` or similar base, though not used)
- `Microsoft.Practices.Unity``IUnityContainer`
- `System.ComponentModel.Composition` — MEF attributes
### Consumers (Inferred):
- Any module resolving `IShellView` via MEF container
- `RaiseNotification` event publishers (via `IEventAggregator`)
---
## 5. Gotchas
1. **NotImplementedException Methods**: `Cleanup()`, `CleanupAsync()`, `InitializeAsync()`, and `InitializeAsync(object parameter)` all throw `NotImplementedException`. Calling these will crash the application.
2. **Misleading XML Comment**: The constructor's documentation states it "Creates a new instance of the TechnologyDomainEditViewModel" — this is incorrect; it creates a `ShellViewModel`.
3. **Hardcoded View Cast**: `GetRegions()` and `ContextMainRegion` cast `View` to the concrete `ShellView` type, violating MVVM separation. If `IShellView` is implemented by a different view type, runtime `InvalidCastException` will occur.
4. **Dead Code**: `LoadViewer()` is defined but never called (commented out in constructor). It also casts `IViewerShellView` to `ShellView`, which appears to be a bug — `IViewerShellView` should likely map to a different view type.
5. **IsDirty Property**: The `IsDirty` property has no setter and always returns `false`. It is unclear if this is intentional or incomplete.
6. **Missing Base Class**: The commented-out inheritance (`//BaseViewModel<ShellViewModel>`) suggests this class was refactored to not use a base ViewModel, but manually implements `INotifyPropertyChanged` instead.

View File

@@ -0,0 +1,97 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/AddCalculatedChannelModule.cs
generated_at: "2026-04-16T11:07:19.006418+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "a6eff6c72a8470eb"
---
# Documentation: AddCalculatedChannelModule
## 1. Purpose
This module provides the "Add Calculated Channel" functionality for the DTS Viewer application. It is a Prism module responsible for registering its associated View (`AddCalculatedChannelView`) and ViewModel (`AddCalculatedChannelViewModel`) with the Unity dependency injection container. The module also defines assembly-level metadata attributes that expose the module's name, image, group, and region for use by the main application shell.
---
## 2. Public Interface
### `AddCalculatedChannelModule` (Class)
Implements `Prism.Modularity.IModule`. The primary module entry point.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `AddCalculatedChannelModule(IUnityContainer unityContainer)` | Accepts an injected `IUnityContainer` instance and stores it in `_unityContainer`. |
| `RegisterTypes` | `void RegisterTypes(IContainerRegistry containerRegistry)` | Calls `Initialize()`. Required by `IModule`. |
| `OnInitialized` | `void OnInitialized(IContainerProvider containerProvider)` | Empty implementation. Required by `IModule`. |
| `Initialize` | `void Initialize()` | Registers `IAddCalculatedChannelView``AddCalculatedChannelView` and `IAddCalculatedChannelViewModel``AddCalculatedChannelViewModel` with Unity. |
### `AddCalculatedChannelModuleNameAttribute` (Class)
Extends `TextAttribute`. Applied at assembly level to expose the module name.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `AddCalculatedChannelModuleNameAttribute()` | Default constructor. |
| Constructor | `AddCalculatedChannelModuleNameAttribute(string s)` | Overload accepting a string (parameter is unused). |
| `AssemblyName` | `override string AssemblyName { get; }` | Returns `AssemblyNames.AddCalculatedChannel.ToString()`. |
| `GetAttributeType` | `override Type GetAttributeType()` | Returns `typeof(TextAttribute)`. |
| `GetAssemblyName` | `override string GetAssemblyName()` | Returns `AssemblyName`. |
### `AddCalculatedChannelModuleImageAttribute` (Class)
Extends `ImageAttribute`. Applied at assembly level to expose module image, name, group, and region metadata.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `AddCalculatedChannelModuleImageAttribute()` | Default constructor. |
| Constructor | `AddCalculatedChannelModuleImageAttribute(string s)` | Overload accepting a string (parameter is unused). |
| `AssemblyImage` | `override BitmapImage AssemblyImage { get; }` | Lazily loads image via `AssemblyInfo.GetImage()`. |
| `AssemblyName` | `override string AssemblyName { get; }` | Returns `AssemblyNames.AddCalculatedChannel.ToString()`. |
| `AssemblyGroup` | `override string AssemblyGroup { get; }` | Returns `eAssemblyGroups.Viewer.ToString()`. |
| `AssemblyRegion` | `override eAssemblyRegion AssemblyRegion { get; }` | Returns `eAssemblyRegion.AddCalculatedChannelRegion`. |
| `GetAttributeType` | `override Type GetAttributeType()` | Returns `typeof(ImageAttribute)`. |
| `GetAssemblyImage` | `override BitmapImage GetAssemblyImage()` | Returns `AssemblyImage`. |
| `GetAssemblyName` | `override string GetAssemblyName()` | Returns `AssemblyName`. |
| `GetAssemblyGroup` | `override string GetAssemblyGroup()` | Returns `AssemblyGroup`. |
| `GetAssemblyRegion` | `override eAssemblyRegion GetAssemblyRegion()` | Returns `AssemblyRegion`. |
---
## 3. Invariants
- **Module Name**: The Prism module name is the string literal `"AddCalculatedChannel"` (set via `[Module(ModuleName = "AddCalculatedChannel")]`).
- **Single Instance Attributes**: Both assembly attributes are declared with `AllowMultiple = false`, ensuring only one of each exists per assembly.
- **Region Assignment**: The module is always associated with `eAssemblyRegion.AddCalculatedChannelRegion`.
- **Group Assignment**: The module always belongs to `eAssemblyGroups.Viewer`.
- **Interface Registration**: Types are registered by interface (`IAddCalculatedChannelView`, `IAddCalculatedChannelViewModel`) rather than concrete types.
---
## 4. Dependencies
### This module depends on:
- `System` - Core .NET framework.
- `System.Windows.Media.Imaging` - For `BitmapImage` used in module image.
- `DTS.Common` - Provides `AssemblyNames` enum and `eAssemblyGroups`, `eAssemblyRegion` enums.
- `DTS.Common.Interface` - Provides `TextAttribute`, `ImageAttribute`, and `AssemblyInfo` base classes/utilities.
- `Prism.Ioc` - For `IContainerProvider` and `IContainerRegistry`.
- `Prism.Modularity` - For `IModule` interface and `ModuleAttribute`.
- `Unity` - For `IUnityContainer` DI container.
### What depends on this module:
- **Inferred**: The main DTS Viewer shell application, which discovers and loads Prism modules via assembly attributes and registers Views/ViewModels for navigation.
- **Inferred**: `IAddCalculatedChannelView` and `IAddCalculatedChannelViewModel` consumers (likely defined in `DTS.Common.Interface` or elsewhere).
---
## 5. Gotchas
1. **Misleading Singleton Comment**: The comment on line 42 states "Register View & View-Model with Unity dependency injection container as a singleton," but `_unityContainer.RegisterType<TFrom, TTo>()` without a `ContainerControlledLifetimeManager` registers types as **transient**, not singleton. The comment appears inaccurate relative to the actual code behavior.
2. **Unused Constructor Parameter**: Both attribute classes have constructors accepting a `string s` parameter that is never used. This is likely required by attribute syntax constraints but serves no functional purpose.
3. **Redundant Image Initialization**: In `AddCalculatedChannelModuleImageAttribute`, the `_img` field is initialized both in the constructor and lazily in the `AssemblyImage` getter. The constructor initialization is overwritten by the getter on first access.
4. **Empty `OnInitialized`**: The `OnInitialized` method is intentionally empty. This is valid but may indicate initialization logic is handled elsewhere or deferred.
5. **ReSharper Suppressions**: The file includes `// ReSharper disable` directives for `RedundantAttributeUsageProperty` and `UnusedParameter.Local`, suggesting known code style issues that were suppressed rather than addressed.

View File

@@ -0,0 +1,115 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/Model/CalculatedChannelCreator.cs
generated_at: "2026-04-16T11:21:42.260506+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "d05bf6b72e9c97be"
---
# Documentation: CalculatedChannelCreator
## 1. Purpose
The `CalculatedChannelCreator` class is a static factory that creates derived data channels from existing test data channels. It supports multiple calculation types including aggregate operations (SUM, AVE, Resultant, HIC), binary operations (Integral, DoubleIntegral, Derivative, Sin, Cos), and specialized 3D IR-Tracc sensor calculations. The module handles sample rate alignment via super-sampling, creates persistent memory-mapped file storage for calculated data, and integrates the results back into the test data hierarchy.
## 2. Public Interface
### `CreateChannels`
```csharp
public static Test.Module.CalculatedChannel[] CreateChannels(
string testId,
string folder,
Calculation calculation,
List<Test.Module.Channel> inputChannels,
string channelName,
int startingNumber,
List<Test.Module.Channel> allChannels,
int clipLength,
out List<string> errorList,
int defaultEncoding)
```
**Behavior:** Main entry point for creating calculated channels. Routes to appropriate internal creation method based on `Calculation` type:
- `ThreeDIRTracc`, `ThreeDIRTraccLowerThorax`, `ThreeDIRTraccAbdomen``Create3DIRTraccChannels`
- `SUM`, `AVE`, `Resultant`, `HIC``CreateChannelsAggregateOperation`
- All others → `CreateChannelsBinaryOperation`
Returns `null` if channel name validation fails or calculation produces no results. Sets `AbsoluteDisplayOrder` on each returned channel starting from `startingNumber`.
### `ValidateChannelName`
```csharp
public static bool ValidateChannelName(
string channelName,
List<Test.Module.Channel> inputChannels,
List<Test.Module.Channel> allChannels,
out List<string> errorList)
```
**Behavior:** Validates that the channel name is non-empty and unique across both `inputChannels` and `allChannels`. Returns `true` if valid (empty error list). If `allChannels` is `null`, returns `true` immediately with no validation performed.
### `ThreeDIRTraccType` (nested enum)
```csharp
public enum ThreeDIRTraccType
{
Thorax,
Abdomen,
LowerThorax
}
```
**Behavior:** Specifies the anatomical mounting position for 3D IR-Tracc sensors, which affects calculation constants (`δ` and `D0`).
---
## 3. Invariants
1. **Channel Number Offset:** All calculated channels use `ChannelNumberCalculationChannelIndicator` (100000) as a base offset added to the provided starting number.
2. **3D IR-Tracc Input Count:** `Create3DIRTraccChannels` asserts that exactly 3 input channels are provided. Failure triggers `System.Diagnostics.Trace.Assert`.
3. **Aggregate Operation Input Count:** `CreateChannelsAggregateOperation` asserts at least 1 input channel is provided.
4. **Sample Rate Compatibility:** For aggregate and 3D IR-Tracc operations, the maximum sample rate must be an integer multiple of all input channel sample rates. If not, `NotSupportedException` is thrown.
5. **Binary Operations:** Only the first channel in `inputChannels` is used for binary operations (Integral, Derivative, Sin, Cos, etc.).
6. **HIC Unit Requirement:** HIC calculations require acceleration in g's. If input engineering units are not "g", data is converted from m/s² using factor `9.80665`.
7. **Super-Sampling Warning:** When input channels have different sample rates, a `PageErrorEvent` is published with `SuperSamplingWarning` resource string.
---
## 4. Dependencies
### This module depends on:
- `DTS.Common.Enums.Sensors` - `SensorConstants` for IR-Tracc physical constants
- `DTS.Common.Utilities.Logging` - `APILogger` for file operation logging
- `DTS.Common.Utils` - `FileUtils` for file deletion
- `DTS.Serialization` - `SliceRaw.File` format handling
- `DTS.Slice.Control` - Test/Event module channel types
- `DTS.Common` - `Constants.ADC_MIDPOINT`, `ZeroMethodType`
- `DTS.Common.Events` - `PageErrorEvent`, `PageErrorArg`
- `DTS.Common.Calculations` - `HeadInjuryCriterion` for HIC calculation
- `DTS.Common.Utilities.Math.Nhtsa` - `Integration`, `Differentiation` classes
- `Prism.Ioc` - `ContainerLocator` for service resolution
- `Prism.Events` - `IEventAggregator` for event publishing
### What depends on this module:
- **Inferred:** `AddCalculatedChannelViewModel` (referenced via `using static` for `ThreeDIRTraccType` context)
- **Inferred:** Any module calling `CreateChannels` to generate derived data channels
---
## 5. Gotchas
1. **Explicit GC.Collect():** `CreatePersistentInformationObject` calls `GC.Collect()` before attempting file deletion to release file handles. This is a heavy operation that may cause performance issues.
2. **Unused Variable:** In `PerformCalculationsAggregate`, the variable `timeAtIndex` is declared and assigned (`var timeAtIndex =`) but the value is never used—the assignment result is discarded.
3. **Debug File Replacement:** `PerformCalculation` (3D IR-Tracc) calls `DiskUtility.ReplaceDataIfNeeded` with hardcoded filenames (`"DISPLEU.txt"`, `"YPOTEU.txt"`, `"ZPOTEU.txt"`). This appears to be debug/test instrumentation left in production code.
4. **ScaleEuData Scaling Logic:** The scaling factor calculation handles bipolar signals by doubling the max value (`max *= 2`), but the scaleFactor calculation differs based on whether max exceeds `short.MaxValue`—one path divides, the other multiplies, which may produce unexpected scaling behavior.
5. **Null Return on Validation Failure:** `CreateChannels` returns `null` if `ValidateChannelName` fails, but the error list is populated via `out` parameter. Callers must check both the return value and error list.
6. **Binary Operations Ignore Additional Channels:** `CreateChannelsBinaryOperation` and `PerformCalculationBinary` only use `inputChannels[0]`. Additional channels in the list are silently ignored.
7. **HIC-Specific Handling:** HIC calculation is performed inside `CreateChannelsAggregateOperation` after channel creation, setting `T1`, `T2`, and `HIC` properties on the calculated channel. This is not visible from the public method signature.

View File

@@ -0,0 +1,41 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T11:21:22.849143+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "013fcfe349498337"
---
# Documentation: DTS.Viewer.AddCalculatedChannel Assembly Configuration
## 1. Purpose
This file provides assembly-level metadata and configuration for the `DTS.Viewer.AddCalculatedChannel` module. It exists to define the module's identity, version, and COM visibility settings within the larger DTS Viewer application. It serves as the build-time configuration for the compiled .NET assembly.
## 2. Public Interface
This file contains no public classes, methods, or functions. It applies the following assembly-level attributes:
* **`AssemblyTitle`**: Set to `"DTS.Viewer.AddCalculatedChannel"`.
* **`AssemblyProduct`**: Set to `"DTS.Viewer.AddCalculatedChannel"`.
* **`AssemblyCopyright`**: Set to `"Copyright © 2017"`.
* **`ComVisible`**: Set to `false`. Prevents types in this assembly from being visible to COM components.
* **`Guid`**: Set to `"6451f3ed-934e-47e3-a1ca-33c223a6507a"`. Identifies the type library ID if the project is exposed to COM.
* **`AssemblyVersion`**: Set to `"1.0.0.0"`.
* **`AssemblyFileVersion`**: Set to `"1.0.0.0"`.
## 3. Invariants
* **COM Visibility:** The attribute `ComVisible(false)` ensures that all types within this assembly are not exposed to COM by default.
* **Versioning:** The assembly and file versions are currently fixed at `1.0.0.0`.
* **Identity:** The assembly is uniquely identified by the GUID `6451f3ed-934e-47e3-a1ca-33c223a6507a`.
## 4. Dependencies
* **Internal Dependencies:**
* `System.Reflection`
* `System.Runtime.CompilerServices`
* `System.Runtime.InteropServices`
* **External Dependencies:** None identified from source alone (other than the standard .NET Framework).
## 5. Gotchas
* **Incomplete Metadata:** The `AssemblyDescription` and `AssemblyCompany` attributes are initialized as empty strings.
* **Hardcoded Version:** The version is hardcoded to `1.0.0.0`. The file contains a commented-out example for auto-incrementing syntax (`"1.0.*"`), but it is not active.
* **Stale Copyright:** The copyright string is hardcoded to 2017.

View File

@@ -0,0 +1,151 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/Resources/TranslateExtension.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/Resources/StringResources.Designer.cs
generated_at: "2026-04-16T11:20:45.009025+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "5726c0d4d71935f1"
---
# Documentation: DTS.Viewer.AddCalculatedChannel.Resources
## 1. Purpose
This module provides localization infrastructure for the "Add Calculated Channel" feature within the DTS Viewer application. It consists of a WPF XAML markup extension (`TranslateExtension`) that enables declarative resource lookups in XAML bindings, and a strongly-typed resource accessor class (`StringResources`) that wraps a `.resx` file containing localized strings for UI elements, calculation types, error messages, and IR-TRACC measurement labels. The module supports the crash test data analysis domain, providing terminology for head injury criterion (HIC), 3D IR-TRACC calculations, and various mathematical operations.
---
## 2. Public Interface
### TranslateExtension (DTS.Viewer.AddCalculatedChannel)
A WPF markup extension for performing localized string lookups in XAML.
```csharp
[MarkupExtensionReturnType(typeof(string))]
public class TranslateExtension : MarkupExtension
```
**Constructor:**
- `TranslateExtension(string key)` — Initializes the extension with the resource key to look up. The key is stored in a private readonly field `_key`.
**Methods:**
- `public override object ProvideValue(IServiceProvider serviceProvider)` — Returns the localized string for the stored key. Returns `#stringnotfound#` if `_key` is null or empty. Returns `#stringnotfound# {key}` if the resource manager returns null for the given key.
**Constants:**
- `private const string NotFound = "#stringnotfound#"` — Fallback string used when a resource lookup fails.
---
### StringResources (DTS.Viewer.AddCalculatedChannel.Resources)
An auto-generated, strongly-typed resource accessor class. This class is `internal`.
```csharp
internal class StringResources
```
**Static Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `ResourceManager` | `global::System.Resources.ResourceManager` | Lazily-initialized cached ResourceManager instance for the `DTS.Viewer.AddCalculatedChannel.Resources.StringResources` resource bundle. |
| `Culture` | `global::System.Globalization.CultureInfo` | Gets or sets the current thread's UI culture for resource lookups. |
**Resource String Properties (static, read-only):**
The following localized string properties are exposed. All return `string`:
- `AddCalculatedChannel` — "Add Calculated Channel"
- `CalculatedChannel_Average` — "Average"
- `CalculatedChannel_IRTRACC3D` — "3D IR-TRACC (upper thorax)"
- `CalculatedChannel_IRTRACC3D_Abdomen` — "3D IR-TRACC (abdomen)"
- `CalculatedChannel_IRTRACC3D_LowerThorax` — "3D IR-TRACC (lower thorax)"
- `CalculatedChannel_IRTRACC3D_Thorax` — "3D IR-TRACC (thorax)"
- `CalculatedChannel_IRTRACC3DAbdomen` — "3D IR-TRACC (abdomen)"
- `CalculatedChannel_IRTRACC3DLowerThorax` — "3D IR-TRACC (lower thorax)"
- `CalculatedChannel_Sum` — "Sum"
- `Calculation` — "Calculation"
- `CALCULATION_Cos` — "Cosine"
- `CALCULATION_Derivative` — "Derivative"
- `CALCULATION_DoubleIntegral` — "Double integral"
- `CALCULATION_Integral` — "Integral"
- `CALCULATION_Sin` — "Sine"
- `CALCULATION_ThreeDIRTracc` — "3D IR-TRACC (upper thorax)"
- `CALCULATION_ThreeDIRTraccAbdomen` — "3D IR-TRACC (abdomen)"
- `CALCULATION_ThreeDIRTraccLowerThorax` — "3D IR-TRACC (lower thorax)"
- `CalculationInputChannel` — "Calculation Input Channel"
- `Channel` — "Channel"
- `ChannelName` — "Channel Name"
- `ClipLengthMS` — "Clip length (ms)"
- `Description` — "Description"
- `HICAccelerationX` — "Acceleration X"
- `HICAccelerationY` — "Acceleration Y"
- `HICAccelerationZ` — "AccelerationZ"
- `HICRequires3Channels` — "Error: Head injury criterion requires 3 channels."
- `InputChannels` — "Input channels"
- `ISOCode` — "ISO Code"
- `NoChannelsIncluded` — "Error: No channels included."
- `ResultantUnitsDontMatch` — "Error: Units don't match for all input channels."
- `SampleRatesDontMatch` — "Error: Sample rates don't match for all input channels."
- `SuperSamplingWarning` — "Calculation contains multiple sample rates. Input will be resampled to the highest sample rate using linear interpolation."
- `ThreeD_IRTracc` — "IR-TRACC"
- `ThreeD_RotPot1` — "R. Pot Y"
- `ThreeD_RotPot2` — "R. Pot Z"
---
## 3. Invariants
1. **TranslateExtension always returns a non-null string.** The `ProvideValue` method guarantees a string return value—either the localized resource, `#stringnotfound#`, or `#stringnotfound# {key}`.
2. **Empty/null key handling differs from missing key handling.** When `_key` is null or empty, the return is exactly `#stringnotfound#`. When `_key` is valid but the resource is missing, the return is `#stringnotfound# {key}` (includes the key name).
3. **StringResources.ResourceManager is lazily initialized and thread-safe.** The property uses a null-check pattern with a temporary variable before assignment.
4. **StringResources is auto-generated.** The class bears `GeneratedCodeAttribute`, `DebuggerNonUserCodeAttribute`, and `CompilerGeneratedAttribute`. Manual modifications will be lost on regeneration.
5. **StringResources.Culture defaults to null.** If not explicitly set, resource lookups will use the current thread's UI culture.
6. **All resource string properties are internal.** They are only accessible within the `DTS.Viewer.AddCalculatedChannel.Resources` namespace or via friend assemblies.
---
## 4. Dependencies
### This module depends on:
- `System` — Core .NET types
- `System.Windows.Markup``MarkupExtension` base class and `MarkupExtensionReturnTypeAttribute`
- `System.Resources``ResourceManager` for resource lookups
- `System.Globalization``CultureInfo` for culture-specific lookups
- `System.CodeDom.Compiler``GeneratedCodeAttribute` (auto-generated code)
- `System.Diagnostics``DebuggerNonUserCodeAttribute`
- `System.Runtime.CompilerServices``CompilerGeneratedAttribute`
- `System.ComponentModel``EditorBrowsableAttribute`
### What depends on this module:
**Inferred from context:** The `TranslateExtension` class is designed for use in XAML files within the `DTS.Viewer.AddCalculatedChannel` namespace. The resource strings reference calculation types, IR-TRACC measurements, and HIC (Head Injury Criterion) parameters, suggesting this module supports a crash test data analysis UI.
**Note:** The actual XAML consumers and other code-behind files that reference `StringResources` are not present in the provided source files.
---
## 5. Gotchas
1. **Duplicate/overlapping resource keys exist.** There appear to be semantically duplicate keys with slightly different naming conventions:
- `CalculatedChannel_IRTRACC3D_Abdomen` and `CalculatedChannel_IRTRACC3DAbdomen` both return "3D IR-TRACC (abdomen)"
- `CalculatedChannel_IRTRACC3D_LowerThorax` and `CalculatedChannel_IRTRACC3DLowerThorax` both return "3D IR-TRACC (lower thorax)"
- `CalculatedChannel_IRTRACC3D` and `CALCULATION_ThreeDIRTracc` both return "3D IR-TRACC (upper thorax)"
This may indicate a naming convention shift or migration artifact. Developers should verify which key is intended for use in new code.
2. **Inconsistent naming conventions.** Some keys use underscores with prefixes (`CALCULATION_*`), others use different patterns (`CalculatedChannel_*`). The rationale for this is unclear from source alone.
3. **HICAccelerationZ lacks a space.** The value is "AccelerationZ" while X and Y variants are "Acceleration X" and "Acceleration Y". This may be a typo in the `.resx` file.
4. **TranslateExtension does not use the Culture property.** The extension calls `StringResources.ResourceManager.GetString(_key)` without passing a culture, meaning it uses the current thread's UI culture. If `StringResources.Culture` has been set to a different value, the extension will not respect it.
5. **IServiceProvider parameter is unused.** The `serviceProvider` parameter in `ProvideValue` is accepted but never used, which is typical for simple markup extensions but worth noting if advanced target-aware behavior is ever needed.

View File

@@ -0,0 +1,37 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/View/AddCalculatedChannelView.xaml.cs
generated_at: "2026-04-16T11:21:57.219744+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "13409539a2c3243c"
---
# Documentation: AddCalculatedChannelView.xaml.cs
## 1. Purpose
This file defines the code-behind class `AddCalculatedChannelView` for a WPF User Control. It serves as the "View" component in the "Add Calculated Channel" module, responsible for initializing the UI components defined in the associated XAML markup. It implements the `IAddCalculatedChannelView` interface, suggesting it is designed for decoupled instantiation, likely via a dependency injection container or a specific UI framework pattern.
## 2. Public Interface
* **`AddCalculatedChannelView` (Class)**
* **Signature:** `public partial class AddCalculatedChannelView : IAddCalculatedChannelView`
* **Description:** The primary class defined in this file. It is a `partial` class, meaning its definition is split between this C# file and the generated code from the XAML file (e.g., `AddCalculatedChannelView.g.cs`). It implements `IAddCalculatedChannelView` from the `DTS.Common.Interface` namespace.
* **`AddCalculatedChannelView()` (Constructor)**
* **Signature:** `public AddCalculatedChannelView()`
* **Description:** The default constructor. It calls `InitializeComponent()`, a standard WPF method that loads and initializes the XAML-defined user interface elements.
## 3. Invariants
* **Partial Definition:** The class is declared `partial`. The code assumes a corresponding XAML file exists (`AddCalculatedChannelView.xaml`) with a matching root element. Without this, the `InitializeComponent()` method would not be found, and compilation would fail.
* **Interface Contract:** The class guarantees it fulfills the contract defined by `IAddCalculatedChannelView`, though the specific members of that interface are not visible in this source file.
## 4. Dependencies
* **Internal Dependencies:**
* `DTS.Common.Interface`: The class implements `IAddCalculatedChannelView` from this namespace.
* **External/Implicit Dependencies:**
* **WPF (Windows Presentation Foundation):** Relies on `System.Windows.Controls.UserControl` (implied by the inheritance structure of a standard `.xaml.cs` file) and the `InitializeComponent()` method generated by the WPF build process.
## 5. Gotchas
* **Namespace Mismatch Suppression:** The file includes `// ReSharper disable CheckNamespace`. This indicates that the declared namespace `DTS.Viewer.AddCalculatedChannel` likely does not match the folder structure inferred by ReSharper (specifically, the file is located in a `View` subfolder, but the namespace does not end in `.View`). This discrepancy may cause navigation issues or confusion regarding project organization standards.
* **Missing Interface Implementation Details:** The source file shows the class implements `IAddCalculatedChannelView`, but no explicit implementation members (properties, methods) are visible. They are either implemented in the XAML (via code-behind bindings) or the interface is empty/marker interface. The exact requirements of the interface cannot be determined from this file alone.

View File

@@ -0,0 +1,178 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.AddCalculatedChannel/ViewModel/AddCalculatedChannelViewModel.cs
generated_at: "2026-04-16T11:21:00.745415+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "5cfd5d272102b3bf"
---
# Documentation: AddCalculatedChannelViewModel
## 1. Purpose
This module provides a ViewModel for the "Add Calculated Channel" feature in the DTS Viewer application. It enables users to create derived data channels from existing test data by applying mathematical transformations (integrals, derivatives, trigonometric functions) or specialized biomechanical calculations (HIC, 3D IR-Tracc, Resultant). The ViewModel manages channel selection UI state, validates user inputs, orchestrates the calculated channel creation via `CalculatedChannelCreator`, and persists changes back to `.dts` test files.
---
## 2. Public Interface
### Public Properties
| Property | Type | Description |
|----------|------|-------------|
| `View` | `IBaseView` | The associated view instance. |
| `Parent` | `IBaseViewModel` | Reference to the parent ViewModel. |
| `ContextSearchRegion` | `object` | Placeholder for context search region. |
| `NotificationRequest` | `InteractionRequest<Notification>` | Raises notification dialogs. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | Raises confirmation dialogs. |
| `HeaderInfo` | `string` | Returns `"AddCalculatedChannelRegion"`. |
| `IsBusy` | `bool` | **Throws `NotImplementedException`** on get/set. |
| `IsDirty` | `bool` | **Throws `NotImplementedException`** on get. |
| `IsAddCalculatedChannelIncluded` | `bool` | Feature inclusion flag. |
| `IncludeGroupNameInISOExport` | `bool` | Controls ISO export formatting. |
| `DefaultDTSEncoding` | `int` | Encoding code page for DTS file operations. |
| `ChannelName` | `string` | Name for the new calculated channel. |
| `ChannelDescription` | `string` | Auto-generated description based on selected calculation and channels. |
| `IsoCode` | `string` | ISO code for the channel (defaults to `"NONE"`). |
| `SingleChannelSelectorVisibility` | `bool` | Controls visibility for single-channel selection UI. |
| `HICChannelSelectorVisibility` | `bool` | Controls visibility for HIC channel selection UI. |
| `MultipleChannelSelectorVisibility` | `bool` | Controls visibility for multi-channel selection UI. |
| `ThreeDIRTRACCVisibility` | `bool` | Controls visibility for 3D IR-Tracc selection UI. |
| `CalculationList` | `CalculationHelper[]` | Lazy-initialized list of available calculations. |
| `SelectedCalculation` | `CalculationHelper` | Currently selected calculation type. |
| `ChannelList` | `ObservableCollection<ITestChannel>` | All available input channels. |
| `ChannelListObjects` | `ObservableCollection<ChannelHelper>` | Wrapped channel objects with `IsIncluded` selection state. |
| `AvailableHICChannels` | `ChannelHelper[]` | Channels with acceleration units valid for HIC calculation. |
| `HICAccelerationX/Y/Z` | `ChannelHelper` | Selected X/Y/Z acceleration channels for HIC. |
| `HICLength` | `int` | HIC calculation length (default: 16). |
| `SourceChannel` | `ITestChannel` | Selected source channel for single-channel calculations. |
| `IRTraccChannelList` | `ObservableCollection<ChannelHelper>` | Valid IR-Tracc channels. |
| `IRTraccChannel` | `ChannelHelper` | Selected IR-Tracc channel. |
| `Pot1ChannelList/Pot2ChannelList` | `ObservableCollection<ChannelHelper>` | Valid potentiometer channels. |
| `Pot1Channel/Pot2Channel` | `ChannelHelper` | Selected potentiometer channels. |
### Public Commands
| Command | Handler | Description |
|---------|---------|-------------|
| `AddCalculatedChannelCommand` | `AddCalculatedChannel(object obj)` | Validates inputs, creates calculated channel(s), and saves to `.dts` file. |
### Public Methods
| Method | Signature | Description |
|--------|-----------|-------------|
| `PublishChanges` | `void PublishChanges()` | **Not implemented** (contains commented-out `NotImplementedException`). |
| `Initialize` | `void Initialize()` | Calls `Initialize(null)`. |
| `Initialize` | `void Initialize(object parameter)` | Sets `Parent` from parameter and subscribes to events. |
| `Activated` | `void Activated()` | Resets UI state: sets default source channel, ISO code, calculation, and channel name. |
| `Cleanup` | `void Cleanup()` | Empty implementation. |
| `Validate` | `bool Validate(ref List<string> errors, ref List<string> warnings, bool displayWindow)` | Validates channel name and calculation-specific requirements. |
### Public Enums
#### `Calculation`
Defines available calculation types with `Description` attributes for display:
| Value | Description |
|-------|-------------|
| `Integral = 0` | "Integral" |
| `DoubleIntegral = 1` | "Double Integral" |
| `Derivative = 2` | "Derivative" |
| `Sin = 3` | "Sin" |
| `Cos = 4` | "Cos" |
| `ThreeDIRTracc = 5` | "3D IR-Tracc" |
| `SUM = 6` | "SUM" |
| `AVE = 7` | "Average" |
| `ThreeDIRTraccAbdomen = 8` | "3D IR-TRACC Abdomen" |
| `ThreeDIRTraccLowerThorax = 9` | "3D IR-TRACC Lower Thorax" |
| `Resultant = 10` | "Resultant" |
| `HIC = 11` | "HIC" |
### Public Nested Classes
#### `ChannelHelper : BasePropertyChanged`
Wraps `ITestChannel` for UI binding with `DisplayName` formatting based on `IsoViewModeStatic.ViewMode` and `IsIncluded` selection state.
#### `CalculationHelper`
Wraps a `Calculation` enum value with localized string display via `StringResources.ResourceManager.GetString("CALCULATION_" + MyCalculation)`.
---
## 3. Invariants
1. **Channel Name Validation**: `ValidateChannelName()` returns `true` only if `ChannelName` is not null or empty.
2. **HIC Calculation Requirements**: `ValidateHIC()` requires all three acceleration channels (`HICAccelerationX`, `HICAccelerationY`, `HICAccelerationZ`) to be non-null.
3. **Resultant Calculation Requirements**: `ValidateResultant()` requires:
- At least one channel with `IsIncluded == true`
- All included channels must have matching `SensitivityUnits`
- All included channels must have matching `SampleRateHz`
4. **Display Order**: New calculated channels are assigned `maxDisplayOrder + 1` from existing channels.
5. **Channel Uniqueness**: `ChannelList` excludes duplicate channels by `ChannelId` during population.
6. **IR-Tracc Channel Filtering**: Channels appear in `IRTraccChannelList` only if:
- `ChannelType` is `Test.Module.AnalogInputChannel`
- `LinearizationFormula` is valid per `LinearizationFormula.IsValid()`
- `ZeroMethod` equals `ZeroMethodType.None`
- `ZeroPoint != 0`
- `FactoryExcitationVoltage != 0`
7. **Potentiometer Channel Filtering**: Channels appear in `Pot1ChannelList`/`Pot2ChannelList` only if:
- `ChannelType` is `Test.Module.AnalogInputChannel`
- `Eu` is `"deg"` or `"deg-ang"` (case-insensitive, trimmed)
- `ZeroMethod` equals `ZeroMethodType.None`
- `FactoryExcitationVoltage != 0`
---
## 4. Dependencies
### This Module Depends On
- `DTS.Common` - Constants, utilities
- `DTS.Common.Base` - `BaseViewModel<T>`, `BasePropertyChanged`
- `DTS.Common.Classes.Viewer.Commands` - `RelayCommand`
- `DTS.Common.DAS.Concepts` - Data concepts
- `DTS.Common.Enums.Sensors` - `ZeroMethodType`
- `DTS.Common.Events` - Event types (`RaiseNotification`, `TestSummaryChangeNotification`, `PageErrorEvent`, `SetSaveButton`, `RefreshTestRequestEvent`)
- `DTS.Common.Interactivity` - `InteractionRequest<T>`, `Notification`, `Confirmation`
- `DTS.Common.Interface` - `IAddCalculatedChannelViewModel`, `IBaseView`, `IBaseViewModel`, `ITestChannel`
- `DTS.Common.Utilities.Logging` - `APILogger`
- `DTS.Common.Utils` - `Utils` class for channel info loading
- `DTS.Slice.Control` - Slice control functionality
- `DTS.Viewer.AddCalculatedChannel.Model` - Model types (inferred)
- `DTS.Serialization` - `Test`, `TestSetup`, `SliceRaw.File`
- `Prism.Events` - `IEventAggregator`
- `Prism.Regions` - `IRegionManager`
- `Unity` - `IUnityContainer`
### Events Subscribed
- `RaiseNotification``OnRaiseNotification`
- `TestSummaryChangeNotification``OnTestSummaryChanged`
### Events Published
- `RaiseNotification`
- `PageErrorEvent`
- `SetSaveButton`
- `RefreshTestRequestEvent`
---
## 5. Gotchas
1. **`IsBusy` and `IsDirty` Throw Exceptions**: Both properties throw `NotImplementedException`. Code paths that access these will fail at runtime.
2. **HIC Save Button Logic Appears Inverted**: In `UpdateSaveButtonVisibility()`, the HIC case sets `IsUsable = true` when acceleration channels are **null** and `IsUsable = false` when they are **not null**. This contradicts the validation logic in `ValidateHIC()` which requires non-null channels. This appears to be a bug.
3. **File Backup Behavior**: The `.dts` backup file (with `BACKUP_FILE_EXTENSION`) is created only if one doesn't already exist. The backup is deleted after successful save only if it was created during that save operation.
4. **Hardcoded Thread.Sleep**: A `Thread.Sleep(10)` exists after file writing in `AddCalculatedChannel()`. Purpose is unclear from source alone.
5. **Lazy Channel Loading**: In `OnTestSummaryChanged()`, if `ts.Channels.FirstOrDefault() == null`, channels are loaded on-demand via `Utils.SetChannelInfo()`. This side effect may not be obvious to callers.
6. **Duplicate Calculated Channel Handling**: `AddCalculatedChannelToTest()` silently overwrites existing calculated channels with matching `ChannelId` by removing the duplicate before adding the new one. A log message is generated but no user confirmation is requested.
7. **`PublishChanges()` Not Implemented**: The method body contains only a commented-out `NotImplementedException`. It is unclear if this is intentional or incomplete.

View File

@@ -0,0 +1,97 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ChartOptions/ChartOptionsModule.cs
generated_at: "2026-04-16T11:06:39.911928+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "bcd5ac559d7f6d8e"
---
# Documentation: ChartOptionsModule.cs
## 1. Purpose
This module serves as the Prism module initializer for the `DTS.Viewer.ChartOptions` component within the DTS Viewer application. It is responsible for registering the chart options View, ViewModel, and Model with the Unity dependency injection container, and provides assembly-level metadata (name, image, group, and region) that the main application uses to identify and display this module as an available component.
---
## 2. Public Interface
### `ChartOptionsModule` (Class)
Implements `Prism.Modularity.IModule`. The primary module entry point for the ChartOptions feature.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `ChartOptionsModule(IUnityContainer unityContainer)` | Accepts an injected `IUnityContainer` instance and stores it in `_unityContainer`. |
| `RegisterTypes` | `void RegisterTypes(IContainerRegistry containerRegistry)` | Calls `Initialize()` to perform type registrations. Required by `IModule`. |
| `OnInitialized` | `void OnInitialized(IContainerProvider containerProvider)` | Empty implementation. Required by `IModule`. |
| `Initialize` | `void Initialize()` | Registers three type mappings with Unity: `IChartOptionsView``ChartOptionsView`, `IChartOptionsViewModel``ChartOptionsViewModel`, `IChartOptionsModel``ChartOptionsModel`. |
### `ChartOptionsModuleNameAttribute` (Class)
Inherits from `TextAttribute`. Assembly-level attribute providing the module's name.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `ChartOptionsModuleNameAttribute()` | Default constructor. |
| Constructor | `ChartOptionsModuleNameAttribute(string s)` | Overloaded constructor; parameter `s` is unused. |
| `AssemblyName` | `override string AssemblyName { get; }` | Returns `AssemblyNames.ChartOptions.ToString()`. |
| `GetAttributeType` | `override Type GetAttributeType()` | Returns `typeof(TextAttribute)`. |
| `GetAssemblyName` | `override string GetAssemblyName()` | Returns `AssemblyName`. |
### `ChartOptionsModuleImageAttribute` (Class)
Inherits from `ImageAttribute`. Assembly-level attribute providing the module's image, name, group, and region metadata.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `ChartOptionsModuleImageAttribute()` | Default constructor. |
| Constructor | `ChartOptionsModuleImageAttribute(string s)` | Overloaded constructor; parameter `s` is unused. |
| `AssemblyImage` | `override BitmapImage AssemblyImage { get; }` | Lazily loads and returns image via `AssemblyInfo.GetImage(AssemblyNames.ChartOptions.ToString())`. |
| `AssemblyName` | `override string AssemblyName { get; }` | Returns `AssemblyNames.ChartOptions.ToString()`. |
| `AssemblyGroup` | `override string AssemblyGroup { get; }` | Returns `eAssemblyGroups.Viewer.ToString()`. |
| `AssemblyRegion` | `override eAssemblyRegion AssemblyRegion { get; }` | Returns `eAssemblyRegion.ChartOptionsRegion`. |
| `GetAttributeType` | `override Type GetAttributeType()` | Returns `typeof(ImageAttribute)`. |
| `GetAssemblyImage` | `override BitmapImage GetAssemblyImage()` | Returns `AssemblyImage`. |
| `GetAssemblyName` | `override string GetAssemblyName()` | Returns `AssemblyName`. |
| `GetAssemblyGroup` | `override string GetAssemblyGroup()` | Returns `AssemblyGroup`. |
| `GetAssemblyRegion` | `override eAssemblyRegion GetAssemblyRegion()` | Returns `AssemblyRegion`. |
---
## 3. Invariants
- The module is registered with Prism under the name `"DTS.Viewer.ChartOptions"`.
- Both assembly attributes are applied with `AllowMultiple = false`, ensuring exactly one instance of each attribute per assembly.
- `AssemblyName` for both attributes always returns `AssemblyNames.ChartOptions.ToString()`.
- `AssemblyGroup` for `ChartOptionsModuleImageAttribute` always returns `eAssemblyGroups.Viewer.ToString()`.
- `AssemblyRegion` for `ChartOptionsModuleImageAttribute` always returns `eAssemblyRegion.ChartOptionsRegion`.
- Type registrations occur exactly once during module initialization via `RegisterTypes`.
---
## 4. Dependencies
### This Module Depends On:
- `System` - Core .NET framework.
- `System.Windows.Media.Imaging` - For `BitmapImage` used in module image.
- `DTS.Common` - Likely contains `AssemblyNames` enum and `AssemblyInfo` utility class.
- `DTS.Common.Interface` - Contains `TextAttribute`, `ImageAttribute`, `eAssemblyGroups`, and `eAssemblyRegion`.
- `DTS.Viewer.ChartOptions.Model` - Contains `IChartOptionsModel` and `ChartOptionsModel` (inferred from usage).
- `Prism.Ioc` - For `IContainerProvider` and `IContainerRegistry`.
- `Prism.Modularity` - For `IModule` and `ModuleAttribute`.
- `Unity` - For `IUnityContainer` and DI registration.
### What Depends On This Module:
- The main DTS Viewer application shell, which discovers and loads this module via Prism's module system.
- The `ChartOptionsView`, `ChartOptionsViewModel`, and `ChartOptionsModel` implementations (referenced but not defined in this file).
---
## 5. Gotchas
1. **Comment claims singleton, code does not enforce it**: The comment in `Initialize()` states "Register View & View-Model with Unity dependency injection container as a singleton," but `RegisterType` without a `ContainerControlledLifetimeManager` registers types as transient (new instance per resolve), not singleton. If singleton behavior is intended, this is a bug.
2. **Unused constructor parameters**: Both `ChartOptionsModuleNameAttribute(string s)` and `ChartOptionsModuleImageAttribute(string s)` accept a string parameter that is never used. This may be dead code or a remnant of a base class contract.
3. **Side effects in property getters**: `AssemblyImage` property has a side effect of assigning to the private `_img` field on every get. Similarly, `_name` and `_group` are assigned in their respective property getters. This is unconventional and could cause unexpected behavior if properties are accessed multiple times.
4. **Empty `OnInitialized` implementation**: The `OnInitialized` method is required by `IModule` but is empty. It is unclear whether this is intentional or represents incomplete initialization logic.

View File

@@ -0,0 +1,129 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ChartOptions/Model/ChartOptionsModel.cs
generated_at: "2026-04-16T11:19:24.422198+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "a2e58408ee52b3f9"
---
# Documentation: ChartOptionsModel.cs
## 1. Purpose
`ChartOptionsModel` is a state-bearing model class that encapsulates all configuration options for chart display within the DTS Viewer application. It manages chart unit types (EU, mV, V, PSD, FFT), time units, Y-axis scaling modes, filter selections, cursor behavior, and axis locking states. The class implements `INotifyPropertyChanged` (via `BasePropertyChanged`) to support data binding and coordinates with a parent `IChartOptionsViewModel` to publish changes and execute commands.
---
## 2. Public Interface
### Class Signature
```csharp
public class ChartOptionsModel : Common.Base.BasePropertyChanged, IChartOptionsModel
```
### Properties
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `DisplayingVolts` | `bool` | `false` | Toggles between Volts (true) and millivolts (false) display. Raises `OnPropertyChanged` for `"MVOrV"` and `"UnitTypeDescription"` when changed. |
| `MVOrV` | `string` | — | Read-only. Returns `"V"` if `DisplayingVolts` is true, otherwise `"mV"`. |
| `IsDigitalChannel` | `bool` | `false` | Indicates whether the channel is digital. |
| `SupportsADC` | `bool` | `true` | Indicates ADC support. |
| `SupportsMV` | `bool` | `true` | Indicates millivolt support. |
| `UnitType` | `ChartUnitTypeEnum` | `ChartUnitTypeEnum.EU` | The unit type for the chart. Changing this sets `ReadData = true` and auto-adjusts `Filter` based on unit type. |
| `UnitTypeDescription` | `string` | — | Read-only. Returns `"V"` or `"mV"` for `ChartUnitTypeEnum.mV`, otherwise returns `UnitType.ToString()`. |
| `TimeUnitType` | `TimeUnitTypeEnum` | `TimeUnitTypeEnum.MS` | Time unit for the X-axis. Sets `ReadData = true` on change. |
| `TimeUnitTypeDescription` | `string` | `"MS"` | String representation of `TimeUnitType`. |
| `SelectedFilter` | `IFilterClass` | `FilterClass(Unfiltered)` | The selected software filter. Sets `ReadData = true` on change. |
| `MinFixedY` | `double` | `0.00` | Minimum Y-axis value for fixed range. |
| `MaxFixedY` | `double` | `0.00` | Maximum Y-axis value for fixed range. |
| `MinFixedT` | `double` | `0.00` | Minimum X-axis (time) value for fixed range. |
| `MaxFixedT` | `double` | `0.00` | Maximum X-axis (time) value for fixed range. |
| `FullScaleValues` | `List<double>` | — | Returns `_euValues` for EU/PSD unit types, otherwise `_fullScaleValues`. |
| `SelectedFullScaleValue` | `double` | `100` | Currently selected full-scale value. |
| `LockedT` | `bool` | `false` | Indicates if the X-axis is locked. |
| `LockedY` | `bool` | `false` | Indicates if the Y-axis is locked. |
| `ShowCursor` | `bool` | `false` | Cursor visibility. Calls `Parent?.ShowCusor(value)` on change. |
| `CurrentCursorValues` | `string` | `""` | String representation of current cursor values. |
| `YRange` | `YRangeScaleEnum` | `YRangeScaleEnum.AutoRange` | Y-axis range mode. Setting to `Fixed` automatically sets `LockedY = true`. |
| `Filter` | `FilterOptionEnum` | `FilterOptionEnum.TestSetupDefault` | Filter option enum. Sets `ReadData = true` on change. |
| `Parent` | `IChartOptionsViewModel` | `null` | Reference to parent view model. |
| `CanPublishChanges` | `bool` | `true` | Controls whether property changes trigger `Parent?.PublishChanges()`. |
| `IsCursorsAvailable` | `bool` | `false` | Indicates if cursors are available for the current context. |
| `T0Cursor` | `bool` | `false` | T0 cursor flag. |
| `MinMaxCursors` | `bool` | `false` | Min/Max cursors flag. |
| `ReadData` | `bool` | `false` | Flag indicating data should be re-read. |
| `IsSaved` | `bool` | — | Read-only auto-property (no setter visible). |
| `DecimateData` | `bool` | `false` | Getter returns `false` if `UnitType` is `PSD` or `FFT`, otherwise returns backing field value. |
| `WidthPoints` | `long` | `0` | Width points for decimation. |
### Commands
| Command | Type | Description |
|---------|------|-------------|
| `ResetZoomCommand` | `DelegateCommand` | Executes `ResetZoomMethod()`, which delegates to `Parent.ResetZoomMethod()`. |
| `ResetTCommand` | `DelegateCommand` | Executes `ResetTMethod()`, which delegates to `Parent.ResetTMethod()`. |
| `SaveToPDFCommand` | `DelegateCommand` | Executes `SaveToPDFMethod()`, which delegates to `Parent.SaveToPDFMethod()`. |
### Methods
| Method | Signature | Description |
|--------|-----------|-------------|
| `ChartOptionsModel` | `ctor()` | Empty parameterless constructor. |
| `SetSelectedFilterToUnfilteredNoRead` | `void SetSelectedFilterToUnfilteredNoRead()` | Sets `_selectedFilter` to `FilterClass(Unfiltered)` with `ReadData = false`. Raises `OnPropertyChanged("SelectedFilter")`. |
| `OnPropertyChanged` | `void OnPropertyChanged(string propertyName)` | Raises `PropertyChanged` event. Conditionally calls `Parent?.PublishChanges()` unless the property is in an exclusion list. |
### Events
| Event | Type | Description |
|-------|------|-------------|
| `PropertyChanged` | `PropertyChangedEventHandler` | Standard INotifyPropertyChanged event. |
---
## 3. Invariants
1. **UnitType → Filter coupling**: When `UnitType` is set to anything other than `EU` or `PSD`, `Filter` is automatically set to `FilterOptionEnum.Unfiltered`. When `UnitType` is `EU` or `PSD`, `Filter` is set to `FilterOptionEnum.TestSetupDefault`.
2. **YRange → LockedY coupling**: Setting `YRange` to `YRangeScaleEnum.Fixed` automatically sets `LockedY = true`.
3. **DecimateData conditional return**: The `DecimateData` getter always returns `false` when `UnitType` is `ChartUnitTypeEnum.PSD` or `ChartUnitTypeEnum.FFT`, regardless of the backing field `_decimateData`.
4. **FullScaleValues selection**: The property returns `_euValues` list when `UnitType` is `EU` or `PSD`; otherwise returns `_fullScaleValues`.
5. **Change publishing exclusion**: The following properties do not trigger `Parent?.PublishChanges()` when changed:
- `CanPublishChanges`, `Parent`, `ReadData`, `UnitTypeDescription`, `ShowCursor`, `LockedT`, `LockedY`, `MVOrV`, `DisplayingVolts`, `DecimateData`, `WidthPoints`
---
## 4. Dependencies
### This Module Depends On
- `System`, `System.Collections.Generic`, `System.ComponentModel` (BCL)
- `DTS.Common` — Base namespace
- `DTS.Common.Base.BasePropertyChanged` — Base class providing `SetProperty` method
- `DTS.Common.Classes.Sensors``FilterClass` implementation
- `DTS.Common.Enums.Viewer``ChartUnitTypeEnum`, `TimeUnitTypeEnum`, `FilterOptionEnum`, `YRangeScaleEnum`
- `DTS.Common.Interface``IChartOptionsModel` (implied), `IChartOptionsViewModel`
- `DTS.Common.Interface.Sensors.SoftwareFilters``IFilterClass`
- `Prism.Commands``DelegateCommand`
### What Depends On This Module
- **Unknown from source alone** — The `IChartOptionsViewModel` interface references this model via the `Parent` property, but concrete consumers are not visible in this file.
---
## 5. Gotchas
1. **Typo in method call**: In the `ShowCursor` setter, the code calls `Parent?.ShowCusor(_showCursor)` — note the spelling "Cusor" instead of "Cursor". This is either a typo in the method name on `IChartOptionsViewModel` or a historical naming quirk.
2. **SetSelectedFilterToUnfilteredNoRead exists as a workaround**: The method `SetSelectedFilterToUnfilteredNoRead()` specifically bypasses the automatic `ReadData = true` behavior that occurs when setting `SelectedFilter` via the property. This suggests the automatic data refresh is sometimes undesirable and requires explicit circumvention.
3. **Inconsistent property setter patterns**: Some properties use `SetProperty(ref _field, value, "PropertyName")` (e.g., `IsDigitalChannel`, `DisplayingVolts`), while others manually implement equality checks and `OnPropertyChanged` calls (e.g., `UnitType`, `MinFixedY`). This inconsistency may reflect different authors or refactoring over time.
4. **IsSaved is unassigned**: The `IsSaved` property has no setter and no initialization. The ReSharper annotation `// ReSharper disable UnassignedGetOnlyAutoProperty` at the top of the file suppresses warnings about this. Accessing this property will return `default(bool)` (`false`).
5. **ReadData side effects are implicit**: Setting `UnitType`, `TimeUnitType`, `SelectedFilter`, or `Filter` silently sets `ReadData = true`. Callers must be aware that these property changes have side effects beyond the property value itself.
6. **Historical comment FB 13120**: The comment `// FB 13120 does not need to set SelectedFilter any more since it's not using enum` and `// FB 13120 use filter class instead of cfc filter enum` reference a past bug/feature (likely FogBugz case 13120) where filter handling was refactored from an enum to a class-based approach.

View File

@@ -0,0 +1,44 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ChartOptions/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T11:18:39.805240+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "fddf8c3b00b320fd"
---
# Documentation: DTS.Viewer.ChartOptions Assembly Configuration
## 1. Purpose
This source file defines the assembly metadata and versioning information for the `DTS.Viewer.ChartOptions` module. It serves as the standard .NET assembly manifest configuration, controlling how the compiled DLL is identified, versioned, and exposed to COM components. This module appears to be a specific component within the larger "DTS Viewer" application suite, likely containing logic related to chart visualization options.
## 2. Public Interface
This file does not contain executable classes, methods, or functions. It strictly defines assembly-level attributes using C# attribute syntax.
* **`AssemblyTitle`**: Set to `"DTS.Viewer.DTS.Viewer.ChartOptions"`. Provides a friendly name for the assembly.
* **`AssemblyDescription`**: Set to an empty string.
* **`AssemblyCompany`**: Set to an empty string.
* **`AssemblyProduct`**: Set to `"DTS.Viewer.DTS.Viewer.ChartOptions"`.
* **`AssemblyCopyright`**: Set to `"Copyright © 2017"`.
* **`AssemblyCulture`**: Set to an empty string (neutral culture).
* **`ComVisible`**: Set to `false`. Makes all types within the assembly invisible to COM components by default.
* **`Guid`**: Set to `"9f161f2a-4fcd-438e-9768-ba96ba104d6c"`. Specifies a unique identifier for the assembly if exposed to COM.
* **`AssemblyVersion`**: Set to `"1.0.0.0"`. Defines the version of the assembly used by the common language runtime.
* **`AssemblyFileVersion`**: Set to `"1.0.0.0"`. Defines the file version number displayed on the file properties.
## 3. Invariants
* **Versioning**: The assembly version is explicitly defined as `1.0.0.0`. It does not use wildcard characters (`*`), meaning the build and revision numbers will not auto-generate; they are fixed.
* **COM Visibility**: By default, no types in this assembly are exposed to COM. To expose a specific type, that type must explicitly override this with `[ComVisible(true)]`.
* **Identity**: The `Guid` `9f161f2a-4fcd-438e-9768-ba96ba104d6c` uniquely identifies this specific assembly in COM scenarios.
## 4. Dependencies
* **Internal Dependencies**: None defined in this file.
* **External Dependencies**:
* `System.Reflection`: Required for the assembly attribute classes.
* `System.Runtime.CompilerServices`: Imported but not actively used for `InternalsVisibleTo` or similar attributes in this snippet.
* `System.Runtime.InteropServices`: Required for the `Guid` and `ComVisible` attributes.
## 5. Gotchas
* **Naming Redundancy**: The `AssemblyTitle` and `AssemblyProduct` are set to `"DTS.Viewer.DTS.Viewer.ChartOptions"`. This appears to be a redundant duplication of the namespace (DTS.Viewer appearing twice). This may be a typo in the project configuration or a specific naming convention for this module.
* **Legacy Format**: This file represents the legacy .NET Framework approach to assembly metadata. If this project has been migrated to the SDK-style `.csproj` format, these attributes may conflict with auto-generated attributes unless `<GenerateAssemblyInfo>` is set to `false` in the project file.
* **Empty Metadata**: `AssemblyDescription` and `AssemblyCompany` are empty. While valid, this results in minimal metadata being embedded in the compiled binary, which can make library identification difficult for external tools or auditing processes.

View File

@@ -0,0 +1,72 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ChartOptions/Resources/TranslateExtension.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ChartOptions/Resources/StringResources.Designer.cs
generated_at: "2026-04-16T11:18:12.490923+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "8d340ea94a701586"
---
# Documentation: DTS.Viewer.ChartOptions Resources
## 1. Purpose
This module provides localization infrastructure for the `DTS.Viewer.ChartOptions` namespace. It consists of a XAML markup extension (`TranslateExtension`) enabling declarative binding to localized strings in UI layouts, and a strongly-typed resource accessor class (`StringResources`) that wraps the underlying `.resx` storage. It exists to decouple UI labels and chart-related text (e.g., "Save Chart", "Min/Max" labels) from the code logic, supporting potential multi-language deployments.
## 2. Public Interface
### Class: `TranslateExtension`
**Namespace:** `DTS.Viewer.ChartOptions`
**Inheritance:** `System.Windows.Markup.MarkupExtension`
This class allows XAML bindings to retrieve localized strings directly.
* **Constructor:** `TranslateExtension(string key)`
* Initializes the extension with the resource key to be looked up.
* **Method:** `public override object ProvideValue(IServiceProvider serviceProvider)`
* Returns the localized string associated with `_key`.
* Returns `#stringnotfound#` if the key is null or empty.
* Returns `#stringnotfound# [key]` if the lookup fails (key not found in resources).
### Class: `StringResources`
**Namespace:** `DTS.Viewer.ChartOptions.Resources`
**Accessibility:** `internal`
A strongly-typed resource class generated by Visual Studio/ResGen. It provides static properties to access string values defined in the resource file.
* **Property:** `static global::System.Resources.ResourceManager ResourceManager`
* Returns the cached `ResourceManager` instance for this assembly.
* **Property:** `static global::System.Globalization.CultureInfo Culture`
* Gets or sets the current UI culture for resource lookups.
* **Resource Properties (Static Strings):**
* `ChartUnitType`: Looks up "Chart Unit Type".
* `FilterOptions_Title`: Looks up "Display Filter".
* `LockT`: Looks up "Lock T".
* `MaxT`: Looks up "Max:".
* `MaxY`: Looks up "Max:".
* `MinT`: Looks up "Min:".
* `MinY`: Looks up "Min:".
* `Range`: Looks up "Range".
* `ResetAll`: Looks up "Reset All".
* `ResetT`: Looks up "Reset T".
* `SaveChart`: Looks up "Save Chart".
* `SaveToPDF`: Looks up "Save to PDF".
* `TimeUnitType`: Looks up "Time Unit Type".
## 3. Invariants
* **Auto-generation:** `StringResources` is auto-generated; manual modifications to `StringResources.Designer.cs` will be overwritten if the tool regenerates the file. Changes must be made to the corresponding `.resx` file.
* **Error Handling:** `TranslateExtension.ProvideValue` will never return `null`. It guarantees a string return, either the valid translation or a specific error constant.
* **Key Requirement:** `TranslateExtension` requires a non-null, non-empty string key to attempt a valid lookup.
## 4. Dependencies
* **Internal Dependencies:**
* `TranslateExtension` depends on `DTS.Viewer.ChartOptions.Resources.StringResources` for the actual resource lookup logic.
* **External Dependencies:**
* `System.Windows.Markup`: Required for `MarkupExtension` and `MarkupExtensionReturnTypeAttribute` (WPF specific).
* `System.Resources`: Used for `ResourceManager`.
* `System.Globalization`: Used for `CultureInfo`.
## 5. Gotchas
* **Missing Key Formatting:** If a resource key is passed to `TranslateExtension` but does not exist in the `.resx` file, the returned string includes the missing key name appended to the error token (e.g., `#stringnotfound# MyMissingKey`). This differs from the empty/null key behavior, which returns only the token `#stringnotfound#`.
* **Duplicate Values:** The source indicates that `MaxT` and `MaxY` both map to the default value "Max:", and `MinT`/`MinY` map to "Min:". While likely intentional for localization reuse, context-specific nuances might be lost if the localization requirements for Time (T) vs Y-axis diverge in other languages.
* **Internal Visibility:** The `StringResources` class is marked `internal`. It is not accessible outside the `DTS.Viewer.ChartOptions` assembly. External assemblies must rely on `TranslateExtension` (if public) or cannot access these resources directly.

View File

@@ -0,0 +1,60 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ChartOptions/View/ChartOptionsView.xaml.cs
generated_at: "2026-04-16T11:18:57.795839+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "2fdf05f68ae69d8d"
---
# Documentation: ChartOptionsView
## 1. Purpose
`ChartOptionsView` is a WPF view component implementing `IChartOptionsView` that provides user interface elements for configuring chart options. It serves as the visual layer for chart-related settings, specifically exposing available filter class options (CFC - likely "Channel Filter Classes" or "Calculated Filter Classes") to the UI for user selection.
---
## 2. Public Interface
### `ChartOptionsView()` (Constructor)
**Signature:** `public ChartOptionsView()`
Initializes the view component by calling `InitializeComponent()`, which loads the associated XAML layout.
### `AvailableCFC` (Property)
**Signature:** `public List<IFilterClass> AvailableCFC { get; }`
**Returns:** A `List<IFilterClass>` containing available filter class options.
**Behavior:** Creates a new instance of `AnalogSettingDefaults` on each access and returns its `FilterOptions` property. This property is read-only (getter only).
---
## 3. Invariants
- The `AvailableCFC` property will never return `null` (assuming `AnalogSettingDefaults.FilterOptions` never returns null, which is not verifiable from this source alone).
- The view always implements `IChartOptionsView` interface contract.
- `InitializeComponent()` must be called exactly once during construction (handled by WPF framework conventions).
---
## 4. Dependencies
### This module depends on:
- `DTS.Common.Interface` - Provides `IChartOptionsView` interface
- `DTS.Common.Interface.Sensors.SoftwareFilters` - Provides `IFilterClass` interface
- `DTS.SensorDB` - Provides `AnalogSettingDefaults` class
### What depends on this module:
- Not determinable from this source file alone. Consumers would be whatever module creates or references `ChartOptionsView` instances.
---
## 5. Gotchas
1. **Object allocation on every property access:** The `AvailableCFC` property instantiates a new `AnalogSettingDefaults` object every time it is read. If this property is data-bound in XAML and accessed frequently, it could create unnecessary object allocations and GC pressure. Consider whether this should be cached or lazy-loaded.
2. **FB 13120 reference:** The comment references "FB 13120" which appears to be an issue/feature tracking identifier. The context or resolution of this tracking item is not available from the source.
3. **Unknown interface contract:** The requirements of `IChartOptionsView` are not visible in this source, so it is unclear if `AvailableCFC` fulfills an interface member or is an additional public member.

View File

@@ -0,0 +1,167 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ChartOptions/ViewModel/ChartOptionsViewModel.cs
generated_at: "2026-04-16T11:18:03.613000+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "7f2f2e90f6f17587"
---
# Documentation: ChartOptionsViewModel
## 1. Purpose
`ChartOptionsViewModel` is a Prism-based view model that manages user-configurable chart display options within the DTS Viewer application. It serves as an intermediary between chart option UI controls and the underlying chart rendering system, handling unit type selection (EU, mV, ADC), axis range configuration, cursor visibility, and PDF export functionality. The module supports multiple parent contexts including `IViewerMainViewModel` and `IPSDReportMainViewModel`, with different default configurations based on the parent type.
---
## 2. Public Interface
### Constructor
```csharp
public ChartOptionsViewModel(
IChartOptionsView view,
IRegionManager regionManager,
IEventAggregator eventAggregator,
IUnityContainer unityContainer)
```
Initializes the view model, sets up the view's DataContext, creates interaction requests, and subscribes to `ChartAxisChangedEvent`.
---
### Properties
| Property | Type | Access | Description |
|----------|------|--------|-------------|
| `Parent` | `IBaseViewModel` | get/set | Reference to the parent view model; used for event filtering. |
| `NotificationRequest` | `InteractionRequest<Notification>` | get | Prism interaction request for notifications. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | get | Prism interaction request for confirmations. |
| `View` | `IBaseView` | get/set | The associated view interface. |
| `Model` | `IChartOptionsModel` | get/set | The chart options model; resolves from container on set. Raises `OnPropertyChanged("Model")`. |
| `ContextSearchRegion` | `object` | get/set | Unused in visible code. |
| `IsMenuIncluded` | `bool` | get/set | Hides base property. |
| `IsNavigationIncluded` | `bool` | get/set | Hides base property. |
| `IsBusy` | `bool` | get/set | Hides base property. |
| `IsDirty` | `bool` | get | Always returns default value; never assigned. |
| `ChartOptionsVisability` | `bool` | get/set | Controls visibility of chart options UI. Raises property changed notification. |
| `ClearMarkersCommand` | `DelegateCommand` | get | Lazy-initialized command that calls `ClearMarkersMethod()`. |
---
### Methods
```csharp
public override void Initialize()
```
Empty override; performs no operations.
```csharp
public override void Initialize(object parameter)
```
Initializes the view model with a parent context. Subscribes to events, resolves the model from Unity container, and configures defaults based on parameter type:
- If `parameter is IViewerMainViewModel`: Sets `Model.DecimateData = true`
- If `parameter is Tuple<IBaseViewModel, string>` where `Item1` is `IPSDReportMainViewModel`: Configures based on `chartType` string ("Graph" vs other)
```csharp
public void ShowMinMaxCursor(bool value)
```
Publishes `CursorShowMinMaxChangedEvent` with the given boolean value.
```csharp
public void ResetZoomMethod()
```
Sets `Model.YRange` to `YRangeScaleEnum.AutoRange` and publishes `ResetZoomChangedEvent` with `true`.
```csharp
public void ResetTMethod()
```
Publishes `ResetZoomChangedEvent` with `false`.
```csharp
public void SaveToPDFMethod()
```
Publishes `SaveToPDFRequestedEvent` with the stored `Directory` path.
```csharp
public void PublishChanges()
```
Publishes `ChartOptionsChangedEvent` with a `ChartOptionsChangedEventArg` containing `ParentVM`, `Model`, and `ChartType`.
```csharp
public void ShowCusor(bool value)
```
Publishes `CursorShowChangedEvent` with the given boolean value.
```csharp
public new void OnPropertyChanged(string propertyName)
```
Raises the `PropertyChanged` event for the specified property name.
---
### Events
```csharp
public new event PropertyChangedEventHandler PropertyChanged
```
Hides the base class event; raised by `OnPropertyChanged`.
---
## 3. Invariants
1. **Model Resolution**: `Model` must be resolved from `IUnityContainer` before use; it is not resolved in the constructor but in `Initialize(object parameter)`.
2. **Event Filtering**: All received events are filtered by comparing `args?.ParentVM` to `Parent`. Events from other parent contexts are ignored.
3. **Publish Guard Pattern**: When programmatically modifying `Model` properties in response to events (e.g., in `OnChartAxisChangedEvent`), `Model.CanPublishChanges` must be set to `false` before modifications and restored to `true` afterward to prevent recursive event publishing.
4. **Log Scale Constraint**: When `chartType == "Graph"`, `Model.MinFixedY` is set to `1e-12` because log scale cannot handle zero.
5. **Unit Type Fallback**: If channels do not support ADC or mV (determined by `AllChannelsSupportADC` / `AllChannelsSupportmV`), the `Model.UnitType` is automatically reset to `ChartUnitTypeEnum.EU`.
---
## 4. Dependencies
### This Module Depends On
| Namespace | Types Used |
|-----------|------------|
| `DTS.Common.Base` | `BaseViewModel<T>`, `IBaseViewModel` |
| `DTS.Common.Enums.Viewer` | `ChartUnitTypeEnum`, `YRangeScaleEnum`, `FilterOptionEnum` |
| `DTS.Common.Enums.Hardware` | `HardwareConstants.IsTSRAIRSerialNumber()` |
| `DTS.Common.Events` | `ChartAxisChangedEvent`, `CursorsAlailableChangedEvent`, `GraphSelectedChannelsNotification`, `CursorShowMinMaxChangedEvent`, `ResetZoomChangedEvent`, `SaveToPDFRequestedEvent`, `ChartOptionsChangedEvent`, `CursorShowChangedEvent`, `CursorsClearChangedEvent` |
| `DTS.Common.Interface` | `IChartOptionsViewModel`, `IChartOptionsModel`, `IChartOptionsView`, `IBaseView`, `IViewerMainViewModel`, `IPSDReportMainViewModel`, `ITestChannel` |
| `DTS.Common.Interactivity` | `InteractionRequest<T>`, `Notification`, `Confirmation` |
| `Prism.Events` | `IEventAggregator` |
| `Prism.Regions` | `IRegionManager` |
| `Prism.Commands` | `DelegateCommand` |
| `Unity` | `IUnityContainer` |
### Modules That Depend On This Module
Cannot be determined from source alone; would require analysis of consumers of `IChartOptionsViewModel`.
---
## 5. Gotchas
1. **Copy-Paste Error in XML Comment**: The constructor's XML documentation states "Creates a new instance of the TestSummaryViewModel" — this is incorrect; the class is `ChartOptionsViewModel`.
2. **Typo: `ChartOptionsVisability`**: Property name should be `ChartOptionsVisibility`.
3. **Typo: `ShowCusor`**: Method name should be `ShowCursor`.
4. **Typo: `OnCursorsAlailableChanged`**: Event handler and event name `CursorsAlailableChangedEvent` should be `CursorsAvailableChanged`.
5. **Hidden Base Members**: Multiple properties (`IsMenuIncluded`, `IsNavigationIncluded`, `IsBusy`, `IsDirty`, `ConfirmationRequest`, `Model`, `PropertyChanged`, `OnPropertyChanged`) use the `new` keyword to hide base class members. This may cause unexpected behavior when casting to base types.
6. **Unused `IsDirty` Property**: The property has only a getter and is never assigned a value, making it perpetually `false` (default).
7. **Commented-Out Constructor Code**: Lines 55-57 are commented out, suggesting initialization logic was moved to `Initialize(object parameter)`.
8. **Hardcoded Magic Strings**: Axis comparison uses literal strings `"Y"` and `"X"` in `OnChartAxisChangedEvent`; `chartType` comparison uses literal `"Graph"`.
9. **ADC/mV Support Detection**: Both `AllChannelsSupportADC` and `AllChannelsSupportmV` use identical logic (checking for TSR AIR serial numbers). The comment indicates this is a temporary implementation that may need future refinement for calculated channels.

View File

@@ -0,0 +1,125 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Filter/FilterModule.cs
generated_at: "2026-04-16T11:06:02.876821+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "ba34bc552f65e535"
---
# Documentation: DTS.Viewer.Filter Module
## 1. Purpose
This module serves as a Prism-based plugin module for the DTS Viewer application, providing filtering functionality. It registers a filter view and view model with the Unity dependency injection container and exposes assembly-level metadata (name, image, region, group) via custom attributes. This metadata is used by the main application to display the module as an available component on the main screen.
---
## 2. Public Interface
### `FilterModule` Class
Implements `Prism.Modularity.IModule`. The primary module entry point for the filter component.
**Constructor:**
```csharp
public FilterModule(IUnityContainer unityContainer)
```
Accepts a Unity container instance via dependency injection and stores it in a private readonly field `_unityContainer`.
**Methods:**
| Method | Signature | Description |
|--------|-----------|-------------|
| `Initialize` | `public void Initialize()` | Registers `IFilterView``FilterView` and `IFilterViewModel``FilterViewModel` with the Unity container. |
| `OnInitialized` | `public void OnInitialized(IContainerProvider containerProvider)` | Empty implementation (no-op). |
| `RegisterTypes` | `public void RegisterTypes(IContainerRegistry containerRegistry)` | Calls `Initialize()`. |
---
### `FilterPropertiesNameAttribute` Class
Inherits from `TextAttribute`. Assembly-level attribute providing the module's display name.
**Constructor:**
```csharp
public FilterPropertiesNameAttribute() : this(null) { }
public FilterPropertiesNameAttribute(string s)
```
The string parameter `s` is accepted but unused; `_assemblyName` is always set to `AssemblyNames.Filter.ToString()`.
**Properties:**
- `public override string AssemblyName { get; }` — Returns `AssemblyNames.Filter.ToString()`.
**Methods:**
- `public override Type GetAttributeType()` — Returns `typeof(TextAttribute)`.
- `public override string GetAssemblyName()` — Returns the `AssemblyName` property value.
---
### `FilterPropertiesImageAttribute` Class
Inherits from `ImageAttribute`. Assembly-level attribute providing the module's image, name, group, and region metadata.
**Constructor:**
```csharp
public FilterPropertiesImageAttribute() : this(null) { }
public FilterPropertiesImageAttribute(string s)
```
The string parameter `s` is accepted but unused.
**Properties:**
| Property | Type | Value |
|----------|------|-------|
| `AssemblyImage` | `BitmapImage` | Loaded via `AssemblyInfo.GetImage(AssemblyNames.Filter.ToString())` |
| `AssemblyName` | `string` | `AssemblyNames.Filter.ToString()` |
| `AssemblyGroup` | `string` | `eAssemblyGroups.Viewer.ToString()` |
| `AssemblyRegion` | `eAssemblyRegion` | `eAssemblyRegion.FilterRegion` |
**Methods:**
- `public override Type GetAttributeType()` — Returns `typeof(ImageAttribute)`.
- `public override BitmapImage GetAssemblyImage()` — Returns `AssemblyImage`.
- `public override string GetAssemblyName()` — Returns `AssemblyName`.
- `public override eAssemblyRegion GetAssemblyRegion()` — Returns `AssemblyRegion`.
- `public override string GetAssemblyGroup()` — Returns `AssemblyGroup`.
---
## 3. Invariants
1. **Module Name**: The module is registered with Prism under the name `"FilterProperties"` (via `[Module(ModuleName = "FilterProperties")]`).
2. **Attribute Usage**: Both `FilterPropertiesNameAttribute` and `FilterPropertiesImageAttribute` are applied at assembly level with `AllowMultiple = false` — they must appear exactly once per assembly.
3. **Registration Pattern**: `IFilterView` and `IFilterViewModel` are registered as transient types (not singletons) via `RegisterType<>`.
4. **Metadata Consistency**: The `AssemblyName` property in both attribute classes always returns `AssemblyNames.Filter.ToString()` — it is not configurable via constructor arguments.
---
## 4. Dependencies
### This module depends on:
- `System` — Core .NET framework.
- `System.Windows.Media.Imaging` — For `BitmapImage` type.
- `DTS.Common` — Provides `AssemblyNames` enum, `AssemblyInfo` static class, `eAssemblyRegion` enum, `eAssemblyGroups` enum.
- `DTS.Common.Interface` — Provides `TextAttribute`, `ImageAttribute` base classes, and interfaces `IFilterView`, `IFilterViewModel`.
- `Prism.Ioc` — Provides `IContainerProvider`, `IContainerRegistry`.
- `Prism.Modularity` — Provides `IModule` interface.
- `Unity` — Provides `IUnityContainer`.
### What depends on this module:
- The main DTS Viewer shell application, which discovers and loads this module at runtime.
- Code that references `FilterView` or `FilterViewModel` (not defined in this file; expected to exist elsewhere in the project).
---
## 5. Gotchas
1. **Unused Constructor Parameter**: Both attribute constructors accept a `string s` parameter that is completely ignored. This is misleading and could confuse developers expecting configurable behavior.
2. **Redundant Method Call**: `RegisterTypes()` simply delegates to `Initialize()`, which is unconventional. Typically, `RegisterTypes` would use the `IContainerRegistry` parameter directly rather than calling a separate method that uses the stored `IUnityContainer`.
3. **Lazy Initialization in Property Getter**: The `AssemblyImage` property getter has a side effect — it assigns to `_img` before returning it. This violates the principle that property getters should be side-effect-free.
4. **Empty `OnInitialized`**: The `OnInitialized` method is explicitly empty. It's unclear whether this is intentional (no post-initialization required) or an oversight.
5. **Type Registration Not Singleton**: The comment in `Initialize()` states "Register View & View-Model... as a singleton," but `RegisterType<>` registers transient types. To register as singleton, `RegisterType<..., ...>(new ContainerControlledLifetimeManager())` would be required. **This appears to be a bug or misleading comment.**

View File

@@ -0,0 +1,57 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Filter/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T11:15:37.389912+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "84c02c8aaa174ca5"
---
# Documentation: DTS.Viewer.Filter AssemblyInfo.cs
## 1. Purpose
This file provides assembly-level metadata for the `DTS.Viewer.Filter` module (based on the file path). It configures .NET assembly attributes including title, version information, COM visibility settings, and a unique GUID for type library identification. This is a standard boilerplate file generated by Visual Studio for .NET Framework projects, used by the runtime and tooling to identify and version the assembly.
## 2. Public Interface
This file contains no public functions, classes, or methods. It consists entirely of assembly-level attributes:
| Attribute | Value |
|-----------|-------|
| `AssemblyTitle` | `"DTS.Viewer.Search"` |
| `AssemblyDescription` | `""` (empty) |
| `AssemblyConfiguration` | `""` (empty) |
| `AssemblyCompany` | `""` (empty) |
| `AssemblyProduct` | `"DTS.Viewer.Search"` |
| `AssemblyCopyright` | `"Copyright © 2017"` |
| `AssemblyTrademark` | `""` (empty) |
| `AssemblyCulture` | `""` (empty) |
| `ComVisible` | `false` |
| `Guid` | `"e958450a-4e86-46bd-8b9a-65fcf8326423"` |
| `AssemblyVersion` | `"1.0.0.0"` |
| `AssemblyFileVersion` | `"1.0.0.0"` |
## 3. Invariants
- `ComVisible(false)` ensures types in this assembly are not visible to COM components by default.
- The `Guid` attribute provides a unique identifier that remains constant for the assembly's lifetime if exposed to COM.
- Version numbers follow the standard four-part format: `Major.Minor.Build.Revision`.
## 4. Dependencies
**This module depends on:**
- `System.Reflection` - For assembly metadata attributes
- `System.Runtime.CompilerServices` - For compiler-related attributes
- `System.Runtime.InteropServices` - For `ComVisible` and `Guid` attributes
**What depends on this module:**
- Cannot be determined from this file alone. This is a leaf configuration file with no downstream dependencies within the codebase.
## 5. Gotchas
**Critical Naming Mismatch:** The file is located at `DTS.Viewer.Filter/Properties/AssemblyInfo.cs`, but both `AssemblyTitle` and `AssemblyProduct` are set to `"DTS.Viewer.Search"`. This strongly suggests:
- The project was copied from `DTS.Viewer.Search` and renamed to `DTS.Viewer.Filter`, but the assembly metadata was never updated, OR
- The folder name is incorrect and should be `DTS.Viewer.Search`
This discrepancy could cause confusion in logs, error messages, deployment artifacts, and when referencing this assembly by name. **This should be verified and corrected.**

View File

@@ -0,0 +1,76 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Filter/Resources/TranslateExtension.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Filter/Resources/StringResources.Designer.cs
generated_at: "2026-04-16T11:15:46.801423+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "6fd260c9e57c0fd4"
---
# Documentation: DTS.Viewer.Filter.Resources
## 1. Purpose
This module provides a mechanism for runtime localization within the `DTS.Viewer.Filter` namespace. It bridges the gap between XAML UI definitions and .NET resource files by exposing a `TranslateExtension` markup extension. This allows UI elements to automatically look up and display localized strings based on a resource key, falling back to a debug-friendly error string when a translation is missing.
## 2. Public Interface
### `TranslateExtension` (Class)
**Namespace:** `DTS.Viewer.Filter`
**Inheritance:** `System.Windows.Markup.MarkupExtension`
This class is a XAML markup extension used to resolve localized strings at runtime.
* **Constructor: `TranslateExtension(string key)`**
* Initializes a new instance of the extension with the specified resource key.
* **Parameter `key`**: The lookup key used to retrieve the string from the resource manager.
* **Method: `ProvideValue(IServiceProvider serviceProvider)`**
* **Return Type:** `object` (attributed to return `string`)
* **Behavior:** Looks up the localized value for the key provided in the constructor.
* If `_key` is null or empty, it returns the constant `NotFound` ("#stringnotfound#").
* It queries `StringResources.ResourceManager.GetString(_key)`.
* If the lookup returns null (key not found), it returns `NotFound` concatenated with a space and the `_key` (e.g., "#stringnotfound# MyMissingKey").
### `StringResources` (Class)
**Namespace:** `DTS.Viewer.Filter.Resources`
**Accessibility:** `internal`
A strongly-typed resource class auto-generated by Visual Studio. It provides access to the culture-specific resources.
* **Property: `ResourceManager`**
* **Return Type:** `System.Resources.ResourceManager`
* **Accessibility:** `internal static`
* **Behavior:** Returns the cached instance of the resource manager for this assembly. It is lazily initialized upon first access.
* **Property: `Culture`**
* **Return Type:** `System.Globalization.CultureInfo`
* **Accessibility:** `internal static`
* **Behavior:** Gets or sets the current UI culture used for resource lookups. Overrides the current thread's `CurrentUICulture` for this specific resource class.
* **Property: `Search`**
* **Return Type:** `string`
* **Accessibility:** `internal static`
* **Behavior:** Returns the localized string associated with the key "Search".
## 3. Invariants
* **Return Type Guarantee:** `TranslateExtension.ProvideValue` is decorated with `[MarkupExtensionReturnType(typeof(string))]`, guaranteeing that the XAML compiler expects a string result.
* **Non-Null Result:** `TranslateExtension.ProvideValue` will never return null. It guarantees a string return, either the localized value or a specific error string.
* **Immutable Key:** The `_key` field in `TranslateExtension` is `readonly`, meaning it cannot be changed after the extension is instantiated.
* **Resource Manager Singleton:** `StringResources.ResourceManager` implements a thread-safe lazy initialization pattern (check-lock-check pattern implied by standard generated code) ensuring only one instance of the manager exists.
## 4. Dependencies
* **Internal Dependencies:**
* `TranslateExtension` depends entirely on `DTS.Viewer.Filter.Resources.StringResources` to perform the actual string lookup.
* **External Framework Dependencies:**
* `System.Windows.Markup`: Used for `MarkupExtension` and `MarkupExtensionReturnTypeAttribute` (indicates a dependency on WPF or a compatible XAML framework).
* `System.Resources`: Used for `ResourceManager`.
* `System.Globalization`: Used for `CultureInfo`.
## 5. Gotchas
* **Fallback String Differentiation:** The behavior differs based on failure mode.
* If the extension is constructed with a null/empty key, the result is exactly `"#stringnotfound#"`.
* If the key is valid but missing from resources, the result is `"#stringnotfound# <key>"`.
* Developers parsing logs or UI tests must account for the space and key suffix in the latter case.
* **Auto-Generated Code:** `StringResources.Designer.cs` is auto-generated. Manual changes to this file will be lost if the project is rebuilt or the `.resx` file is modified. Resource keys must be added via the `.resx` designer or XML.
* **Internal Visibility:** The `StringResources` class is `internal`. While `TranslateExtension` can access it, other assemblies cannot directly access the `ResourceManager` or specific properties like `Search` without reflection or an accessor class.

View File

@@ -0,0 +1,54 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Filter/View/FilterView.xaml.cs
generated_at: "2026-04-16T11:15:53.285154+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "172c435d25b31364"
---
# Documentation: FilterView
## 1. Purpose
This module provides the code-behind implementation for `FilterView`, a WPF view component within the DTS Viewer application's filtering subsystem. It serves as a visual interface for filter-related functionality, implementing the `IFilterView` interface to integrate with the broader application architecture (likely following a view-pattern such as MVVM or MVP). The view's visual layout is defined in the associated XAML file (`FilterView.xaml`), which is not included in this source.
## 2. Public Interface
### `FilterView` (Class)
**Signature:**
```csharp
public partial class FilterView : IFilterView
```
**Description:** A WPF partial class representing a filter view component. Implements `IFilterView` from `DTS.Common.Interface`.
#### Constructor
**Signature:**
```csharp
public FilterView()
```
**Description:** Default constructor that initializes the XAML component by calling `InitializeComponent()`. This is the standard WPF pattern for loading and parsing the associated XAML markup at runtime.
## 3. Invariants
- The class is `partial`, indicating it is paired with generated code (typically from XAML compilation).
- `InitializeComponent()` must be called in the constructor for the view to function correctly—this is a WPF framework requirement.
- The view must implement `IFilterView`, though the specific interface members are not visible in this source file.
## 4. Dependencies
### This module depends on:
- `DTS.Common.Interface` — provides the `IFilterView` interface that this class implements.
### What depends on this module:
- Cannot be determined from this source file alone. The view is likely instantiated by a presenter, view model, or dependency injection container within the `DTS.Viewer.Filter` module or a related module.
## 5. Gotchas
- **Namespace mismatch suppression:** The comment `// ReSharper disable CheckNamespace` indicates the file's namespace (`DTS.Viewer.Filter`) may not match the expected folder structure (`DTS.Viewer.Modules.DTS.Viewer.Filter`). This could cause confusion when navigating the codebase or for tools that rely on folder-namespace alignment.
- **Interface members not visible:** The specific members required by `IFilterView` are not shown in this code-behind. They may be implemented in the XAML (via code generation) or the interface may be empty/marker-only—this cannot be determined without the interface definition.
- **No visible logic:** All behavior is presumably handled via XAML bindings or code-behind in the XAML file, which is not provided.

View File

@@ -0,0 +1,131 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Filter/ViewModel/FilterViewModel.cs
generated_at: "2026-04-16T11:15:18.686742+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "0bfa10177d1e439d"
---
# Documentation: FilterViewModel
## 1. Purpose
`FilterViewModel` is a Prism-based MVVM ViewModel that manages a search/filter input control within the DTS Viewer application. It handles user input for filtering data, publishes filter changes via an event aggregator, and manages placeholder text behavior (showing default text when empty, clearing on focus). The module participates in a loosely-coupled event system allowing other components to react to filter parameter changes without direct references.
---
## 2. Public Interface
### Class: `FilterViewModel`
**Inherits:** `BaseViewModel<IFilterViewModel>`
**Implements:** `IFilterViewModel`
#### Constructor
```csharp
public FilterViewModel(IFilterView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
```
Initializes the ViewModel, sets up the View's DataContext, creates interaction requests, subscribes to `FilterParameterChangedEvent`, and initializes `_filterParam` to the default search text.
---
#### Properties
| Property | Type | Access | Description |
|----------|------|--------|-------------|
| `View` | `IBaseView` | get/set | The associated Filter View. |
| `Parent` | `IBaseViewModel` | get/set | The parent ViewModel passed during initialization. |
| `Requester` | `IBaseViewModel` | get/set | Identifies the originator of filter operations. Raises `PropertyChanged` on set. |
| `IsMenuIncluded` | `bool` | get/set | Hides inherited member. Purpose unclear from source. |
| `IsNavigationIncluded` | `bool` | get/set | Hides inherited member. Purpose unclear from source. |
| `IsBusy` | `bool` | get/set | Hides inherited member. Purpose unclear from source. |
| `IsDirty` | `bool` | get | Hides inherited member. Always returns default `false`. |
| `ContextSearchRegion` | `object` | get/set | Purpose unclear from source. |
| `SearchButtonVisability` | `bool` | get/set | Controls visibility state of a search button. Raises `PropertyChanged` on set. |
| `FilterParam` | `string` | get/set | The current filter parameter value. Publishing `FilterParameterChangedEvent` is suppressed when transitioning between `FilterParamDefault` and empty string. |
| `NotificationRequest` | `InteractionRequest<Notification>` | get | Interaction request for notifications. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | get | Interaction request for confirmations. Hides inherited member. |
---
#### Events
```csharp
public new event PropertyChangedEventHandler PropertyChanged
```
Hides inherited event. Raised via `OnPropertyChanged(string propertyName)`.
---
#### Methods
```csharp
public override void Initialize(object parameter)
```
Sets `Parent` and `Requester` to the provided parameter (cast to `IBaseViewModel`).
```csharp
private void OnFilterParameterChanged(FilterParameterArgs args)
```
Event handler for `FilterParameterChangedEvent`. Only updates local `_filterParam` when `args.Requester` is `null` (documented as a workaround for landing page revisit behavior, referencing issue 15641).
---
#### Commands
| Command | Action Method | Behavior |
|---------|---------------|----------|
| `ClickedCommand` | `ClickedCommandAction()` | Empty implementation—no operation performed. |
| `GotFocusActionCommand` | `GotFocusAction()` | Clears `FilterParam` to empty string if it equals `FilterParamDefault`. |
| `LostFocusActionCommand` | `LostFocusAction()` | Resets `FilterParam` to `FilterParamDefault` if it is null or empty. |
---
## 3. Invariants
1. **Default Filter Text:** `FilterParam` is initialized to `FilterParamDefault` (value from `Resources.StringResources.Search`).
2. **Placeholder Behavior:** The combination of `GotFocusActionCommand` and `LostFocusActionCommand` ensures the filter input displays placeholder text when empty and clears it on focus.
3. **Event Publishing Suppression:** `FilterParameterChangedEvent` is NOT published when:
- `FilterParam` transitions from `FilterParamDefault` to empty string
- `FilterParam` is set to `FilterParamDefault`
4. **Event Subscription:** The ViewModel subscribes to `FilterParameterChangedEvent` during construction and remains subscribed for its lifetime.
5. **Initialization Requirement:** `Initialize(object parameter)` expects `parameter` to be castable to `IBaseViewModel`; behavior is undefined if it is not.
---
## 4. Dependencies
### This Module Depends On:
- `DTS.Common.Base``BaseViewModel<T>`, `IBaseView`, `IBaseViewModel`
- `DTS.Common.Events``FilterParameterChangedEvent`, `FilterParameterArgs`
- `DTS.Common.Interactivity``InteractionRequest<T>`, `Notification`, `Confirmation`
- `DTS.Common.Interface``IFilterView`, `IFilterViewModel`
- `Prism.Commands``DelegateCommand`
- `Prism.Events``IEventAggregator`
- `Prism.Regions``IRegionManager`
- `Unity``IUnityContainer`
- `DTS.Viewer.Filter.Resources.StringResources``Search` resource string
### What Depends On This Module:
- **Unclear from source alone.** Consumers would reference `IFilterViewModel` and/or instantiate `FilterViewModel` via DI container.
---
## 5. Gotchas
1. **Member Hiding with `new` Keyword:** Seven members use `new` to hide inherited members from `BaseViewModel<IFilterViewModel>` (`IsMenuIncluded`, `IsNavigationIncluded`, `IsBusy`, `IsDirty`, `ConfirmationRequest`, `PropertyChanged`, `OnPropertyChanged`). This breaks polymorphic behavior—if base class methods access these members, they will use the base implementation, not the derived one. This may cause subtle bugs.
2. **Typo in Property Name:** `SearchButtonVisability` is misspelled (should be "Visibility"). This typo is exposed publicly and may propagate to XAML bindings.
3. **Unused Command:** `ClickedCommand` has an empty action body. It is exposed publicly but performs no operation.
4. **Redundant Storage:** `_eventAggregator` and `_unityContainer` are stored as private properties after being passed to the base constructor, suggesting potential redundancy or unclear ownership.
5. **Non-Functional `IsDirty` Property:** The property only has a getter and never returns a meaningful value (always `false`). It is unclear if this is intentional or incomplete implementation.
6. **ReSharper Suppressions:** The file includes 7 ReSharper suppressions (`CheckNamespace`, `InconsistentNaming`, `UnassignedGetOnlyAutoProperty`, `NotAccessedField.Local`, `RedundantDefaultMemberInitializer`, `UnusedAutoPropertyAccessor.Local`), indicating known code quality issues that were suppressed rather than resolved.
7. **Magic Null Check:** The `OnFilterParameterChanged` handler uses `args.Requester == null` as a sentinel for "landing page revisit" scenario. This implicit contract is fragile and should be documented more explicitly or replaced with an enum/flag.

View File

@@ -0,0 +1,88 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/GraphModule.cs
generated_at: "2026-04-16T11:05:54.984178+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "b6bfcd5e53808ea8"
---
# Documentation: DTS.Viewer.Graph Module
## 1. Purpose
This module serves as the Prism module definition for the `DTS.Viewer.Graph` component within the DTS Viewer application. Its primary role is to register graph-related views and view models with the Unity dependency injection container during application startup. Additionally, it defines assembly-level attributes (`GraphNameAttribute` and `GraphImageAttribute`) that provide metadata—such as the assembly name, display image, and region assignment—likely used by the main application shell to dynamically discover and display this module.
## 2. Public Interface
### Classes
#### `GraphModule`
Implements `Prism.Modularity.IModule`. The entry point for the module's configuration.
* **`GraphModule(IUnityContainer unityContainer)`**
* Constructor that accepts an `IUnityContainer` instance via dependency injection and stores it in a readonly field.
* **`void RegisterTypes(IContainerRegistry containerRegistry)`**
* Implements `IModule.RegisterTypes`. Calls the local `Initialize()` method to perform type registrations. Note that it ignores the passed `IContainerRegistry` in favor of the stored `IUnityContainer`.
* **`void OnInitialized(IContainerProvider containerProvider)`**
* Implements `IModule.OnInitialized`. Currently contains no implementation logic.
* **`void Initialize()`**
* Registers types with the Unity container.
* **Mappings:**
* `IGraphView``GraphView`
* `IGraphViewModel``GraphViewModel`
* `ITestDataSeriesView``TestDataSeriesView`
* `ITestDataSeriesViewModel``TestDataSeriesViewModel`
#### `GraphNameAttribute`
Inherits from `DTS.Common.Interface.TextAttribute`. Applied at the assembly level to define the module's name.
* **`GraphNameAttribute()`**
* Default constructor. Sets the internal assembly name to `AssemblyNames.Graph.ToString()`.
* **`GraphNameAttribute(string s)`**
* Overloaded constructor. The parameter `s` is accepted but ignored; the assembly name is hardcoded to `AssemblyNames.Graph.ToString()`.
* **`override string AssemblyName`** (Property)
* Returns the stored assembly name string.
* **`override Type GetAttributeType()`**
* Returns `typeof(TextAttribute)`.
* **`override string GetAssemblyName()`**
* Returns the `AssemblyName` property value.
#### `GraphImageAttribute`
Inherits from `DTS.Common.Interface.ImageAttribute`. Applied at the assembly level to provide display metadata (image, group, region).
* **`GraphImageAttribute()` / `GraphImageAttribute(string s)`**
* Constructors. The string parameter `s` is ignored. Initializes the image using `AssemblyInfo.GetImage`.
* **`override BitmapImage AssemblyImage`** (Property)
* Loads and returns a `BitmapImage` by calling `AssemblyInfo.GetImage(AssemblyNames.Graph.ToString())`.
* **`override string AssemblyName`** (Property)
* Returns `AssemblyNames.Graph.ToString()`.
* **`override string AssemblyGroup`** (Property)
* Returns `eAssemblyGroups.Viewer.ToString()`.
* **`override eAssemblyRegion AssemblyRegion`** (Property)
* Returns `eAssemblyRegion.GraphRegion`.
* **Methods:** `GetAttributeType()`, `GetAssemblyImage()`, `GetAssemblyName()`, `GetAssemblyGroup()`, `GetAssemblyRegion()` return the values of the respective properties described above.
## 3. Invariants
* **Module Name:** The module is identified by the string "Graph" via the `[Module(ModuleName = "Graph")]` attribute.
* **Attribute Uniqueness:** `GraphNameAttribute` and `GraphImageAttribute` are applied at the assembly level with `AllowMultiple = false`, ensuring only one instance of each exists per assembly.
* **Naming Consistency:** Both attribute classes hardcode the assembly name lookup to `AssemblyNames.Graph`, ensuring the metadata matches the module identity.
* **Region Assignment:** The module is statically assigned to `eAssemblyRegion.GraphRegion`.
## 4. Dependencies
### Internal Dependencies
* **`DTS.Common`**: Uses `AssemblyNames`, `eAssemblyGroups`, `eAssemblyRegion`, and `AssemblyInfo`.
* **`DTS.Common.Interface`**: Defines base classes `TextAttribute`, `ImageAttribute` and interfaces `IGraphView`, `IGraphViewModel`, `ITestDataSeriesView`, `ITestDataSeriesViewModel`.
* **Local Views/ViewModels**: References `GraphView`, `GraphViewModel`, `TestDataSeriesView`, `TestDataSeriesViewModel` (types not provided in source, but referenced in `Initialize`).
### External Dependencies
* **`Prism.Ioc`**: Uses `IContainerProvider`, `IContainerRegistry`.
* **`Prism.Modularity`**: Implements `IModule`.
* **`Unity`**: Uses `IUnityContainer` and `Unity` attributes.
* **`System.Windows.Media.Imaging`**: Uses `BitmapImage` for image handling.
## 5. Gotchas
* **Unused Constructor Parameters:** Both `GraphNameAttribute(string s)` and `GraphImageAttribute(string s)` accept a string parameter that is completely ignored. This suggests a legacy API or a design intended for future expansion that was never implemented.
* **Side Effects in Property Getters:** The `AssemblyImage` property getter in `GraphImageAttribute` performs logic (`_img = AssemblyInfo.GetImage(...)`). Accessing this property triggers image loading every time, which could be a performance concern if accessed frequently, though the private field `_img` is reassigned each time.
* **Mixed Container Abstractions:** The `RegisterTypes` method receives an `IContainerRegistry` (Prism abstraction) but ignores it. Instead, it calls `Initialize()`, which uses the concrete `IUnityContainer` injected via the constructor. This bypasses Prism's container abstraction, making it harder to swap containers later.
* **Commented Code:** The `Initialize` method contains commented-out registrations for `ITestDataView` and `ITestDataViewModel`. It is unclear if this is dead code or a feature in progress.

View File

@@ -0,0 +1,220 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/Model/TestDataSeries.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/Model/TestDataSeriesModel.cs
generated_at: "2026-04-16T11:14:33.699820+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "1630e6f30be700ba"
---
# Documentation: DTS.Viewer.Graph Module - Data Series Models
## 1. Purpose
This module provides the data models for representing and transforming test channel data into graphable series within the DTS Viewer application. `TestDataSeries` serves as the primary data transfer object holding X/Y values, metadata, and computed statistics for a single graphable channel. `TestDataSeriesModel` acts as a factory/processor that transforms raw `ITestChannel` data into `TestDataSeries` objects, handling time-series, FFT (Fast Fourier Transform), and PSD (Power Spectral Density) conversions with optional filtering and windowing. Together, they bridge the gap between raw binary sensor data and the visualization layer.
---
## 2. Public Interface
### TestDataSeries Class
**Namespace:** `DTS.Viewer.Graph.Model`
**Inherits:** `Common.Base.BasePropertyChanged`
**Implements:** `ITestDataSeries`
#### Properties
| Property | Type | Description |
|----------|------|-------------|
| `HIC` | `bool` | Indicates if Head Injury Criteria data is present. |
| `HICValue` | `string` | Formatted HIC value. |
| `T1Time`, `T2Time` | `string` | T1/T2 timestamp strings for HIC calculations. |
| `TestGroup` | `string` | Group identifier for the test. |
| `TestId` | `string` | Unique test identifier. |
| `TestSetupName` | `string` | Name of the test setup configuration. |
| `ChannelId` | `string` | Channel identifier. |
| `Xvalue` | `double[]` | Array of X-axis values (time or frequency). |
| `Yvalue` | `double[]` | Array of Y-axis values (amplitude, magnitude, or PSD). |
| `GraphColor` | `Brush` | WPF brush for graph rendering; getter creates new `SolidColorBrush` from internal `byte[]`. |
| `HardwareChannel` | `string` | Hardware channel name (auto-property). |
| `GroupName` | `string` | Channel group name (auto-property). |
| `SWAAF` | `string` | Software anti-aliasing filter setting (auto-property). |
| `Bridge` | `string` | Bridge type identifier (auto-property). |
| `HWAAF` | `string` | Hardware anti-aliasing filter rate (auto-property). |
| `SampleRate` | `string` | Sample rate in Hz (auto-property). |
| `ISOCode`, `ISOChannelName` | `string` | ISO-related identifiers (auto-properties). |
| `UserCode`, `UserChannelName` | `string` | User-defined identifiers (auto-properties). |
| `ChannelName`, `Description` | `string` | Channel naming and description (auto-properties). |
| `SensorSN` | `string` | Sensor serial number (auto-property). |
| `SensorSNDisplay` | `string` | Display-friendly serial number; returns `"N/A"` if test-specific embedded per `SensorConstants.IsTestSpecificEmbedded()`. |
| `EngineeringUnits` | `string` | Engineering units string (auto-property). |
| `Excitation` | `string` | Excitation voltage (auto-property). |
| `Polarity` | `string` | Sensor polarity (auto-property). |
| `MinY`, `MaxY`, `AvgY`, `StdDevY` | `string` | Statistical values; default to `Strings.Table_NA`. |
| `PeakMagnitude` | `double` | Peak magnitude for FFT data; default `0`. |
| `PeakFrequency` | `double` | Frequency of peak magnitude; default `0`. |
| `GRMS` | `double` | Root-mean-squared acceleration for PSD; default `0`. |
| `FFT` | `bool` | Indicates if series contains FFT/PSD data; default `false`. |
| `T0EUValue` | `string` | T0 value string; default empty. |
| `RecordingMode` | `string` | Recording mode description (auto-property). |
| `IsSaved` | `bool` | Read-only auto-property (getter only). |
#### Methods
```csharp
public void SetStatsFromYValues()
```
Sets `AvgY`, `StdDevY`, `MinY`, `MaxY`, `T0EUValue` from internal `Yvalue` array. Formats using `"G5"` format string.
```csharp
public void SetStatsFromYValues(double[] values)
```
Overload that accepts an external `double[]` array. Handles null/empty arrays by setting all stats to `NaN` (displayed as `Table_NA`).
```csharp
public void SetStatsFromChannel(ITestChannel channel)
```
Copies pre-calculated statistics from an `ITestChannel` instance using `channel.MinY`, `channel.MaxY`, `channel.AveY`, `channel.StdDevY`, `channel.T0Value`.
---
### TestDataSeriesModel Class
**Namespace:** `DTS.Viewer.Graph`
**Implements:** `IBaseModel`
#### Properties
| Property | Type | Description |
|----------|------|-------------|
| `Parent` | `IGraphViewModel` | Parent view model reference. |
| `_eventAggregator` | `IEventAggregator` | Prism event aggregator for publishing progress events. |
| `ErrorMessage` | `string` | Error message string with property change notification. |
| `IsSaved` | `bool` | Read-only auto-property. |
#### Methods
```csharp
public Task<ITestDataSeries> GetTestDataAsync(ITestChannel channel, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)
```
Async wrapper returning `GetTestData()`. **Warning:** Lacks `await` operators (runs synchronously per compiler warning suppression).
```csharp
public Task<List<ITestDataSeries>> GetTestDataAsync(List<ITestChannel> channels, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)
```
Async wrapper for batch channel processing. Catches `OutOfDataException` and re-throws with context. Optionally adds envelope channel if `psdSettings.ShowEnvelope` is true.
```csharp
public List<ITestDataSeries> GetTestData(List<ITestChannel> channels, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)
```
Synchronous batch processing. Maps each channel through `GetTestData()`. Handles `OutOfDataException` with sample index context.
```csharp
public ITestDataSeries GetTestData(ITestChannel channel, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)
```
Returns `AddTestChannelToChart()` result.
```csharp
public TestDataSeries AddTestChannelToChart(ITestChannel channel, IChartOptionsModel chartOptions, bool bVolts, IPSDReportSettingsModel psdSettings = null)
```
**Primary processing method.** Reads binary channel data via `Serialization.SliceRaw.File.Reader.ReadChannelsBinaryData()`, then branches based on `chartOptions.UnitType`:
- **FFT mode** (`ChartUnitTypeEnum.FFT` with `psdSettings == null`): Sets `FFT = true`, populates `PeakFrequency`, `PeakMagnitude`, calculates stats.
- **Regular time-series** (`psdSettings == null`): Handles HIC data if present, applies time unit multiplier, copies stats from channel.
- **PSD mode** (`psdSettings != null`): Trims data to selected range, applies optional low/high pass filters, computes PSD via `FftSharp.Transform.PSD_Welch()`, calculates GRMS.
Returns `null` if `channel.ErrorMessage` is not empty.
```csharp
private ITestDataSeries GetEnvelopeChannel(List<ITestDataSeries> data)
```
Creates a synthetic "envelope" series by taking the maximum Y-value at each frequency index across all input series. Sets `FFT = true`, color to black.
```csharp
private double CalculateGRMS(double[] freq, double[] psd)
```
Calculates Grms using numerical integration of PSD. Uses logarithmic interpolation formula; handles `N = -1` edge case separately. Returns `Math.Sqrt(aRMS.Sum())`.
---
## 3. Invariants
1. **Array Length Consistency**: `Xvalue` and `Yvalue` arrays should have matching lengths after processing by `TestDataSeriesModel`.
2. **FFT Flag Consistency**: When `FFT == true`, `Xvalue` represents frequency (Hz) and `Yvalue` represents magnitude or PSD. When `FFT == false`, `Xvalue` represents time.
3. **Statistics Default**: `MinY`, `MaxY`, `AvgY` default to `Strings.Table_NA` (not null or empty string).
4. **GraphColor Thread Safety**: `GraphColor` getter creates a new `SolidColorBrush` on each call; the underlying color data is stored as `byte[] _graphColorARGB` to ensure thread safety (per comment referencing issue #34455).
5. **FFT/PSD Filter Bypass**: When `chartOptions.UnitType` is `FFT` or `PSD`, `channel.SoftwareFilter` is forcibly set to `"none"` before reading data.
6. **PSD Data Length**: PSD calculations require input length to be an even power of 2; `Utils.GetEnclosingPower2()` is used to resize the array with zero-padding if necessary.
7. **HIC Validity**: `HIC` is only set to `true` when `channel.HIC != 0` AND `channel.T2Sample > 0`.
---
## 4. Dependencies
### TestDataSeries Dependencies
**External Dependencies:**
- `System.Windows.Media` - `Brush`, `SolidColorBrush`, `Color`, `Colors`
- `DTS.Common.Enums.Sensors` - `SensorConstants` for serial number validation
- `DTS.Common.Interface` - `ITestDataSeries` interface
- `DTS.Common.Strings` - Localized string constants (`Table_NA`)
- `DTS.Common.Base` - `BasePropertyChanged` for INPC implementation
**Dependents (Inferred):**
- `TestDataSeriesModel` - Primary consumer/factory
- Graph view models and charting components (via `ITestDataSeries`)
### TestDataSeriesModel Dependencies
**External Dependencies:**
- `System.Windows.Media` - Color types
- `Prism.Events` - `IEventAggregator` for event publishing
- `FftSharp` - FFT/PSD transforms (`Transform.PSD_Welch`, `Transform.FFTfreq`, `WindowType`, `WindowAveragingType`)
- `Exocortex.DSP` - `PassFilter.LowPass`/`HighPass` filtering
**Internal Dependencies:**
- `DTS.Common.Interface` - `ITestChannel`, `ITestDataSeries`, `IGraphViewModel`, `IChartOptionsModel`, `IPSDReportSettingsModel`, `IBaseModel`
- `DTS.Common.Enums.Viewer` - `ChartUnitTypeEnum`, `TimeUnitTypeEnum`, `Reports.WindowType`, `Reports.WindowAveragingType`
- `DTS.Common.Enums.Sensors` - `SensorConstants.BridgeType.DigitalInput`
- `DTS.Common.Enums.DASFactory` - `DFConstantsAndEnums.RecordingMode`
- `DTS.Common.Converters` - `EnumDescriptionTypeConverter`
- `DTS.Common.Exceptions` - `OutOfDataException`
- `DTS.Common.Events` - `GraphChannelReadCalcProgressChangedEvent`, `GraphChannelReadCalcProgressChangedEventArgs`
- `DTS.Common.Utilities.Logging` - `APILogger`
- `DTS.Common.Utils` - `Utils.GetEnclosingPower2()`
- `DTS.Common.Strings` - Localized strings
- `Serialization.SliceRaw.File.Reader` - `ReadChannelsBinaryData()` for binary data deserialization
- `ChannelFilter` - `AdHoc` filter constant
**Dependents (Inferred):**
- Graph view models implementing `IGraphViewModel`
- PSD report generation components
---
## 5. Gotchas
1. **Async Methods Are Not Truly Async**: Both `GetTestDataAsync` overloads have suppressed compiler warning CS1998 and run synchronously. The `async` keyword is misleading—these methods will block the calling thread.
2. **GraphColor Getter Allocates on Every Call**: The `GraphColor` property getter instantiates a new `SolidColorBrush` on every access. Frequent access in UI binding scenarios could cause unnecessary allocations.
3. **PSD Frequency Array Mutation**: In PSD processing, `freq[0] = 1` forcibly sets the first frequency bin to 1 Hz, potentially overwriting the actual DC component value from `FftSharp.Transform.FFTfreq()`.
4. **CalculateStdDev Uses Population Formula Incorrectly**: The method divides by `(values.Length - 1)` (sample standard deviation) but does not check for single-element arrays, which would cause division by zero.
5. **T0EUValue Naming Is Misleading**: Per the source comment: *"this is the T0 value regardless of units ... it's not really EU but since it's already in use I'm not going to change it"* — historical naming debt.
6. **Envelope Channel Returns Empty Series on Null Input**: `GetEnvelopeChannel()` returns a default `TestDataSeries()` if input list is null or empty, rather than returning null or throwing.
7. **IEPE Bridge Hardcoded**: The constant `IEPE_BRIDGE = "IEPE"` is used for special-casing excitation display, but the value is not sourced from a shared constant.
8. **Digital Channel Detection Uses String Prefix**: `channel.Bridge.StartsWith(SensorConstants.BridgeType.DigitalInput.ToString())` relies on string matching rather than enum comparison.
9. **GRMS Calculation Has Index Bounds Check**: The loop condition `i < psd.Length - 2 && i < freq.Length - 2` skips the last two elements, which is correct for the pairwise calculation but may silently drop data if arrays have different lengths.

View File

@@ -0,0 +1,105 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/Properties/AssemblyInfo.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/Properties/Annotations.cs
generated_at: "2026-04-16T11:14:19.143964+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "530eff79443974f8"
---
# Documentation: DTS.Viewer.Graph Properties
## 1. Purpose
The `DTS.Viewer.Graph` module defines a component within the larger "DTS Viewer" application, ostensibly responsible for graph-related functionality. The provided source files serve administrative and tooling roles: `AssemblyInfo.cs` establishes the assembly's identity, version, and metadata, while `Annotations.cs` provides a comprehensive set of code analysis attributes (sourced from JetBrains) to enhance static analysis, null-checking, and IDE support within the project.
## 2. Public Interface
### Assembly Metadata (`AssemblyInfo.cs`)
This file configures the assembly-level attributes for `DTS.Viewer.Graph.dll`.
* **`AssemblyTitle`**: Set to `"Graph"`.
* **`AssemblyProduct`**: Set to `"Graph"`.
* **`AssemblyCopyright`**: Set to `"Copyright © 2017"`.
* **`ComVisible`**: Set to `false`, making types invisible to COM components.
* **`Guid`**: `61261c58-c32e-4dea-a87a-d7f956f28b4d` (COM TypeLib ID).
* **`AssemblyVersion`**: `"1.0.0.0"`.
* **`AssemblyFileVersion`**: `"1.0.0.0"`.
### Code Annotations (`Annotations.cs`)
This file defines the namespace `DTS.Viewer.Graph.Annotations`, containing numerous attributes and enums used for static code analysis. These types do not affect runtime behavior but instruct the IDE (ReSharper/Rider) on code contracts and usage.
**Nullability and Contracts:**
* `CanBeNullAttribute`: Indicates a value may be `null`.
* `NotNullAttribute`: Indicates a value should never be `null`.
* `ItemNotNullAttribute` / `ItemCanBeNullAttribute`: Applied to collections or `Task`/`Lazy` to indicate the nullability of contained items.
* `ContractAnnotationAttribute`: Describes method input/output dependencies (e.g., `null => null`).
* `PureAttribute`: Indicates a method has no side effects.
* `MustUseReturnValueAttribute`: Indicates a method's return value must be utilized.
**Code Usage and Reflection:**
* `UsedImplicitlyAttribute`: Marks symbols used via reflection or external libraries to suppress "unused" warnings.
* `MeansImplicitUseAttribute`: Applied to other attributes to indicate that targets should be considered "used".
* `PublicAPIAttribute`: Marks API that should not be removed as it is public-facing.
* `ImplicitUseKindFlags` (Enum): Flags defining how a symbol is used (`Access`, `Assign`, `InstantiatedWithFixedConstructorSignature`, etc.).
* `ImplicitUseTargetFlags` (Enum): Flags defining target scope (`Itself`, `Members`, `WithMembers`).
**String and Formatting:**
* `StringFormatMethodAttribute`: Marks a method as a string format method (like `string.Format`).
* `RegexPatternAttribute`: Indicates a parameter is a regex pattern.
* `LocalizationRequiredAttribute`: Indicates if a string should be localized.
**Assertion and Control Flow:**
* `AssertionMethodAttribute`: Marks a method as an assertion (halts control flow on failure).
* `AssertionConditionAttribute`: Marks a parameter as the condition for an assertion.
* `AssertionConditionType` (Enum): Defines assertion types (`IS_TRUE`, `IS_FALSE`, `IS_NULL`, `IS_NOT_NULL`).
* `TerminatesProgramAttribute`: **[Obsolete]** Use `ContractAnnotation("=> halt")` instead.
**Collections and LINQ:**
* `CollectionAccessAttribute`: Describes how a method affects a collection.
* `CollectionAccessType` (Enum): Flags for `None`, `Read`, `ModifyExistingContent`, `UpdatedContent`.
* `InstantHandleAttribute`: Indicates a delegate/enumerable parameter is handled during the method execution.
* `LinqTunnelAttribute`: Marks a method as a pure LINQ method with postponed enumeration.
* `NoEnumerationAttribute`: Indicates an `IEnumerable` parameter is not enumerated.
**ASP.NET MVC and Razor Specifics:**
* `AspMvcActionAttribute`, `AspMvcControllerAttribute`, `AspMvcAreaAttribute`, `AspMvcViewAttribute`: Hints for MVC parameters.
* `AspMvc*LocationFormatAttribute`: Various attributes for specifying view location formats (e.g., `AspMvcAreaViewLocationFormatAttribute`).
* `RazorSectionAttribute`, `RazorImportNamespaceAttribute`, `RazorDirectiveAttribute`: Hints for Razor syntax.
**XAML Specifics:**
* `XamlItemsControlAttribute`: Marks a type as an ItemsControl for XAML analysis.
* `XamlItemBindingOfItemsControlAttribute`: Hints at DataContext binding types.
**Miscellaneous:**
* `NotifyPropertyChangedInvocatorAttribute`: Marks a method as a property change notifier.
* `SourceTemplateAttribute`: Marks an extension method as a source template for code completion.
* `MacroAttribute`: Defines macros for source templates.
* `NoReorderAttribute`: Prevents member reordering in the IDE.
## 3. Invariants
* **COM Visibility:** The assembly is configured with `ComVisible(false)`, guaranteeing that types are not exposed to COM by default.
* **Versioning:** The assembly version is strictly defined as `1.0.0.0` in the source; automatic versioning (e.g., using wildcards) is commented out.
* **Namespace Consistency:** All annotation attributes reside strictly within the `DTS.Viewer.Graph.Annotations` namespace.
* **Attribute Usage:** The attributes in `Annotations.cs` are strictly for metadata; they contain no runtime logic (constructors only set properties).
## 4. Dependencies
* **Internal Dependencies:**
* `System`: Used by `Annotations.cs` for the base `Attribute` type and `Type`, `FlagsAttribute`, etc.
* `System.Reflection`: Used by `AssemblyInfo.cs`.
* `System.Runtime.CompilerServices`: Used by `AssemblyInfo.cs`.
* `System.Runtime.InteropServices`: Used by `AssemblyInfo.cs` for `ComVisible` and `Guid`.
* **External Consumers:**
* The `DTS.Viewer.Graph` assembly is likely consumed by other modules in the "DTS Viewer" solution (inferred from the `Modules` directory structure).
* The `Annotations.cs` types are consumed by the C# compiler and static analysis tools (IDEs like ReSharper or Rider).
## 5. Gotchas
* **Third-Party Code Inclusion:** The `Annotations.cs` file is explicitly licensed under the MIT License and copyrighted by JetBrains (2016). It is a standard boilerplate file often included in projects for ReSharper compatibility. Developers should not modify the logic here, but may update the file if a newer version of the JetBrains annotations is required.
* **Obsolete Attribute:** The `TerminatesProgramAttribute` is marked `[Obsolete]` in the source. New code should use `[ContractAnnotation("=> halt")]` instead.
* **Empty Description:** The `AssemblyDescription` attribute in `AssemblyInfo.cs` is currently an empty string, which may result in sparse metadata for the compiled DLL.
* **Static Analysis Dependency:** The attributes in `Annotations.cs` have no effect if the code is analyzed by tools that do not recognize them (e.g., standard Visual Studio without ReSharper). However, they do not cause runtime errors.

View File

@@ -0,0 +1,104 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/Resources/TranslateExtension.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/Resources/StringResources.Designer.cs
generated_at: "2026-04-16T11:13:28.138314+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "ea967aac84c55893"
---
# Documentation: DTS.Viewer.Graph.Resources
## 1. Purpose
This module provides localization infrastructure for the `DTS.Viewer.Graph` namespace. It enables XAML-based string localization through a WPF markup extension (`TranslateExtension`) backed by a strongly-typed resource class (`StringResources`). The resources defined here support user-facing messaging for chart operations, data filtering validation, and file export functionality (PDF/CSV).
---
## 2. Public Interface
### `TranslateExtension` (class)
**Namespace:** `DTS.Viewer.Graph`
**Inheritance:** `System.Windows.Markup.MarkupExtension`
**Attribute:** `[MarkupExtensionReturnType(typeof(string))]`
A XAML markup extension that resolves localized strings from the resource manager at runtime.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `TranslateExtension(string key)` | Initializes the extension with the resource key to look up. The `key` parameter is stored in a readonly field `_key`. |
| Method | `override object ProvideValue(IServiceProvider serviceProvider)` | Returns the localized string for `_key` via `StringResources.ResourceManager.GetString(_key)`. Returns `NotFound` if `_key` is null or empty. Returns `NotFound + " " + _key` if the key is not found in resources. |
**Constants:**
- `private const string NotFound = "#stringnotfound#"` — Sentinel value returned when a resource key cannot be resolved.
---
### `StringResources` (class)
**Namespace:** `DTS.Viewer.Graph.Resources`
**Accessibility:** `internal`
**Attribute:** `[GeneratedCode]`, `[DebuggerNonUserCode]`, `[CompilerGenerated]`
An auto-generated strongly-typed resource class. Do not edit manually; regenerate from `.resx` file.
| Member | Signature | Description |
|--------|-----------|-------------|
| Property | `static ResourceManager ResourceManager` | Lazily initializes and returns a cached `ResourceManager` instance bound to `"DTS.Viewer.Graph.Resources.StringResources"`. |
| Property | `static CultureInfo Culture` | Gets or sets the culture used for resource lookups. Defaults to `null` (uses current thread's `CurrentUICulture`). |
**Resource String Properties (all `internal static string`):**
| Property Name | Purpose |
|---------------|---------|
| `BadDataFromCustomFilter` | Error message for filter frequency causing out-of-bounds data. Format placeholders: `{0}` (frequency), `{1}` (additional info). |
| `BadDataFromTestSetupDefaultFilter` | Error message for test setup default filter issues. Format placeholder: `{0}`. |
| `BadDataUnfilteredUnknown` | Error message for unviewable channel data. Format placeholder: `{0}`. |
| `ReadingChannelData` | Status message: "Reading channel data...." |
| `SavePDFError` | Error message for chart PDF save failure. |
| `SavePDFSuccess` | Success message for chart PDF save. Format placeholders: `{0}`, `{1}`, `{2}`, `{3}`. |
| `SaveReportCSVError` | Error message for report CSV save failure. |
| `SaveReportCSVSuccess` | Success message for report CSV save. Format placeholder: `{0}` (path). |
| `SaveReportPDFError` | Error message for report PDF save failure. |
| `SaveReportPDFSuccess` | Success message for report PDF save. Format placeholder: `{0}` (path). |
---
## 3. Invariants
1. **Key immutability:** `_key` in `TranslateExtension` is `readonly` and set only at construction.
2. **Non-null return:** `TranslateExtension.ProvideValue` never returns `null`. It always returns either a valid localized string or a `NotFound` sentinel (with optional key suffix).
3. **Fallback behavior:** If `StringResources.ResourceManager.GetString(_key)` returns `null`, the extension returns `"#stringnotfound# " + _key`.
4. **Empty key handling:** If `_key` is `null` or empty string, `ProvideValue` returns exactly `"#stringnotfound#"` without a trailing space or key.
5. **Auto-generation constraint:** `StringResources` class is tool-generated. Manual edits will be lost upon regeneration.
---
## 4. Dependencies
**This module depends on:**
- `System` (core types)
- `System.Windows.Markup` (`MarkupExtension` base class, `MarkupExtensionReturnTypeAttribute`)
- `System.Resources` (`ResourceManager`)
- `System.Globalization` (`CultureInfo`)
- `System.CodeDom.Compiler` (`GeneratedCodeAttribute`)
- `System.Diagnostics` (`DebuggerNonUserCodeAttribute`)
- `System.Runtime.CompilerServices` (`CompilerGeneratedAttribute`)
**Dependents (inferred):**
- XAML files within `DTS.Viewer.Graph` that use `{x:Static}` or `{local:Translate}` markup extensions for localized strings.
- Code within `DTS.Viewer.Graph` that directly references `StringResources` properties for message formatting.
---
## 5. Gotchas
1. **Sentinel value is private:** The `NotFound` constant is `private`, so consuming code cannot programmatically check if a lookup failed by comparing against the sentinel. The sentinel string `"#stringnotfound#"` is effectively hardcoded in behavior.
2. **Key leakage in fallback:** When a key is not found, the returned string includes the key name (`"#stringnotfound# " + _key`). This could expose internal resource key names to end users in production if keys are missing.
3. **Inconsistent fallback format:** Empty/null keys return `"#stringnotfound#"` (no trailing space), while missing keys return `"#stringnotfound# " + _key` (with space and key). This inconsistency may complicate string comparison or testing.
4. **Internal visibility:** `StringResources` is `internal`, so it cannot be accessed from outside the `DTS.Viewer.Graph` assembly. External assemblies must use `TranslateExtension` in XAML or have no access to these resources.
5. **Designer file coupling:** The `.resx` file backing `StringResources` is not included in the provided source. The actual string values and any additional resources are defined elsewhere and regenerated into this designer file.

View File

@@ -0,0 +1,112 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/View/GraphView.xaml.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/View/TestDataView.xaml.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/View/TestDataSeriesView.xaml.cs
generated_at: "2026-04-16T11:14:59.450875+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "8c5a8096c69954ca"
---
# Documentation: DTS.Viewer.Graph Views
## 1. Purpose
This module provides WPF view components for rendering and exporting graphical test data within the DTS Viewer application. It contains three XAML code-behind classes—`GraphView`, `TestDataView`, and `TestDataSeriesView`—that implement view interfaces from `DTS.Common.Interface`. The primary functionality resides in `TestDataSeriesView`, which supports exporting chart data to PDF reports and CSV files (specifically for Power Spectral Density data). The module integrates with ComponentOne charting and PDF libraries for visualization and document generation.
---
## 2. Public Interface
### GraphView
**Signature:** `public partial class GraphView : IGraphView`
- **`GraphView()`** - Default constructor. Calls `InitializeComponent()` to load the XAML-defined UI. No other behavior.
---
### TestDataView
**Signature:** `public partial class TestDataView : ITestDataView`
- **`TestDataView()`** - Default constructor. Calls `InitializeComponent()`. Contains extensive commented-out zoom functionality (mouse handlers, reversible frame drawing) that is not active.
---
### TestDataSeriesView
**Signature:** `public partial class TestDataSeriesView : ITestDataSeriesView`
- **`TestDataSeriesView()`** - Default constructor. Calls `InitializeComponent()`.
- **`bool SaveReportToPDF(string directory)`** - Generates a PDF report containing:
- Test setup name and test ID from the first data series
- Chart image rendered as PNG and embedded
- A tabular summary of channel names, sample rates, and gRMS values with color indicators
- Returns `true` on success, `false` on exception. Throws `DirectoryNotFoundException` if directory is null/whitespace (caught internally).
- **`bool SaveReportToCSV(string directory)`** - Exports PSD (Power Spectral Density) data to CSV format:
- Header row: "Frequency" followed by channel names
- Units row: "Hz" followed by engineering units in format `{units}^2/Hz`
- Data rows: X values (frequency) and corresponding Y values for each channel
- Returns `true` on success, `false` on exception.
- **`void MainChart_OnMouseWheel(object sender, MouseWheelEventArgs e)`** - Event handler (currently empty implementation; zoom logic commented out).
- **`void MainChart_OnKeyUp(object sender, KeyEventArgs e)`** - Event handler (empty implementation).
- **`void obj_DataPointChanged(object sender, EventArgs e)`** - Event handler (currently empty; data point label update logic commented out).
---
### AxisExtension (Static Helper Class)
**Signature:** `public static class AxisExtension`
- **`double GetDispMin(this Axis axis)`** - Extension method calculating display minimum based on `ActualMin`, `Value`, `ActualMax`, and `Scale`.
- **`double GetDispMax(this Axis axis)`** - Extension method calculating display maximum based on `ActualMin`, `Value`, `ActualMax`, and `Scale`.
---
## 3. Invariants
- **PDF Paper Size:** Determined by `System.Globalization.RegionInfo.CurrentRegion.IsMetric` — uses `PaperKind.A4` for metric regions, `PaperKind.Letter` otherwise.
- **Data Series Access:** `SaveReportToPDF` and `SaveReportToCSV` assume `MainChart.DataContext` is castable to `TestDataSeriesViewModel` with a non-null `GraphDataSeries` property.
- **Data Series Uniformity:** CSV export assumes all data series have equal-length `Xvalue` and `Yvalue` arrays (loop condition checks all series).
- **Color Casting:** PDF export assumes `ds.GraphColor` is castable to `System.Windows.Media.SolidColorBrush`.
- **File Naming:** Both export methods generate filenames using the current `DateTime` with specific formatting patterns.
---
## 4. Dependencies
### This module depends on:
- **DTS.Common.Interface** — Provides `IGraphView`, `ITestDataView`, `ITestDataSeriesView` interfaces
- **DTS.Common.Utilities.Logging** — Provides `APILogger` for logging operations and exceptions
- **DTS.Common.Utils** — Provides `FileUtils.GetEncoding(int)`
- **C1.WPF.Chart** — ComponentOne FlexChart library
- **C1.WPF.C1Chart** — ComponentOne chart components (`Axis`, `ImageFormat`)
- **C1.WPF.C1Chart.Extended** — Extended chart functionality
- **C1.WPF.Pdf** — ComponentOne PDF generation (`C1PdfDocument`, `PaperKind`, `Font`, `Pen`)
- **System.Windows** — WPF core (UI elements, input, media)
- **System.IO** — File and directory operations
### What depends on this module:
- **Unknown from source alone** — The interfaces (`IGraphView`, `ITestDataView`, `ITestDataSeriesView`) suggest consumption by a presentation layer or DI container, but concrete consumers are not visible in these files.
---
## 5. Gotchas
1. **Extensive Dead Code:** Both `TestDataView` and `TestDataSeriesView` contain large blocks of commented-out functionality including zoom/pan features, mouse event handling, and data point tracking. This suggests incomplete refactoring or feature rollback.
2. **Tight ViewModel Coupling:** `SaveReportToPDF` and `SaveReportToCSV` directly cast `MainChart.DataContext` to the concrete `TestDataSeriesViewModel` type rather than using an interface, creating tight coupling.
3. **Silent Failure Pattern:** Both export methods catch all exceptions, log them, and return `false` without rethrowing. Callers receive no exception details beyond the boolean result.
4. **Encoding Fallback:** `SaveReportToCSV` attempts to get a specific encoding by code page, falling back to `Encoding.Default` on failure. This could cause inconsistent file encoding across different systems.
5. **File Path Construction:** Both methods construct file paths using string concatenation with `"\\"` rather than `Path.Combine()` for the filename portion (though `Path.Combine` is used elsewhere).
6. **Empty Event Handlers:** `MainChart_OnKeyUp` and `MainChart_OnMouseWheel` are wired but have empty or commented-out implementations — unclear if they are placeholders or remnants.
7. **AxisExtension Usage Unclear:** The `AxisExtension` class provides zoom-related calculations, but no code in these files appears to call these methods.

View File

@@ -0,0 +1,114 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/ViewModel/GraphViewModel.cs
generated_at: "2026-04-16T11:13:10.472796+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "cd4107fac05f80cd"
---
# GraphViewModel Documentation
## 1. Purpose
`GraphViewModel` is the ViewModel component for the Graph module within the DTS Viewer application. It serves as the mediator between the graph view (`IGraphView`) and the underlying data layer, managing chart visualization state, handling user notifications, and coordinating event-driven communication with parent ViewModels. The class supports multiple initialization contexts—either as a child of `IViewerMainViewModel` or `IPSDReportMainViewModel`—with different subscription behaviors and UI configurations based on the context (e.g., "DataSelect" mode vs. default/result mode).
---
## 2. Public Interface
### Constructor
```csharp
public GraphViewModel(IGraphView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
```
Initializes the ViewModel with its associated view, region manager for navigation, event aggregator for pub/sub messaging, and Unity container for dependency resolution. Sets the view's `DataContext` to itself and instantiates interaction requests.
### Properties
| Property | Type | Access | Description |
|----------|------|--------|-------------|
| `View` | `IGraphView` | get; private set | The associated graph view instance. |
| `DataSeriesView` | `ITestDataSeriesView` | get; set | The data series view used for chart rendering. |
| `NotificationRequest` | `InteractionRequest<Notification>` | get; private set | Interaction request for displaying notifications. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | get; private set | Interaction request for displaying confirmations (shadows base member). |
| `ContextGraphRegion` | `object` | get; set | Gets/sets the content of the `GraphRegion` on the view; raises `OnPropertyChanged` on set. |
| `MessageText` | `string` | get; set | Status message text; default is `"Please select Event(s) to export data"`. |
| `MessageVisibility` | `bool` | get; set | Controls visibility of the message panel; triggers `FireVisibilities()` on set. |
| `ProgressPercent` | `double` | get; set | Progress percentage for loading operations; default `0D`. |
| `ProgressText` | `string` | get; set | Progress status text; default `"Reading channel data..."`. |
| `ProgressVisibility` | `bool` | get; set | Controls visibility of progress indicators; triggers `FireVisibilities()` on set. |
| `GraphInfoVisibility` | `bool` | get; set | Controls visibility of graph info panel; triggers `FireVisibilities()` on set. |
| `GraphVisibility` | `bool` | get | Computed as `!MessageVisibility`. |
| `HeaderInfo` | `string` | get | Returns `"GraphRegion"`. |
| `IsBusy` | `bool` | get; set | Busy state indicator (shadows base member). |
| `IsDirty` | `bool` | get | Always returns `false` (shadows base member). |
### Methods
```csharp
public override void Initialize()
```
Empty override; no behavior.
```csharp
public override void Initialize(object parameter)
```
Primary initialization logic. Behavior depends on `parameter` type:
- **If `IViewerMainViewModel`**: Calls `Subscribe()` and sets `Parent` and `DataSeriesView`.
- **If `Tuple<IBaseViewModel, string>` where `Item1` is `IPSDReportMainViewModel`**: Calls `SubscribeDataSelect()` or `SubscribeResult()` based on `Item2` value (`"DataSelect"` vs. default). Configures chart scrollbars and actions based on mode.
### Events
```csharp
public new event PropertyChangedEventHandler PropertyChanged
```
Shadows base `PropertyChanged` event; raised via `OnPropertyChanged(string)`.
---
## 3. Invariants
1. **Parent Matching**: Event handlers `OnTestSelectedCountChanged` and `OnGraphSelectedCountChanged` will early-return if `Parent != arg.ParentVM` or `Parent != arg?.ParentVM` respectively.
2. **GraphVM Identity Check**: `OnGraphChannelsReadCompleted` and `OnGraphChannelReadCalcProgressChangedEvent` require `this == arg.GraphVM` to proceed.
3. **Null Argument Handling**: `OnGraphChannelsReadCompleted` returns immediately if `arg` is null.
4. **Progress Bounds**: `ProgressPercent` is only updated if `arg.ProgressPercent >= 0`.
5. **Visibility Relationships**: `GraphVisibility` is always the logical inverse of `MessageVisibility`.
6. **Initialization Contract**: `Initialize(object parameter)` expects either `IViewerMainViewModel` or a specific `Tuple<IBaseViewModel, string>` pattern; other types result in no initialization.
---
## 4. Dependencies
### This Module Depends On:
- **C1.WPF.C1Chart** - ComponentOne charting library (used for `AxisScrollBar` type casting)
- **DTS.Common.Base** - `BaseViewModel<T>`, `IBaseViewModel`, `IBaseModel`
- **DTS.Common.Events** - Event types: `RaiseNotification`, `GraphSelectedChannelCountNotification`, `TestSummaryCountNotification`, `TestModificationChangedEvent`, `GraphChannelsReadCompletedNotification`, `GraphChannelReadCalcProgressChangedEvent`
- **DTS.Common.Interactivity** - `InteractionRequest<T>`, `Notification`, `Confirmation`
- **DTS.Common.Interface** - `IGraphViewModel`, `IGraphView`, `ITestDataSeriesView`, `ITestDataSeriesViewModel`, `ITestModificationModel`, `IViewerMainViewModel`, `IPSDReportMainViewModel`
- **Prism.Events** - `IEventAggregator`, `ThreadOption`
- **Prism.Regions** - `IRegionManager`
- **Unity** - `IUnityContainer`
### Concrete Type Dependencies (Internal):
- `GraphView` - Referenced in `ContextGraphRegion` property
- `TestDataSeriesView` - Referenced in `Initialize()` for chart configuration
- `TestDataSeriesViewModel` - Referenced in `GetTestDataSeriesView()` for PSD subscription
---
## 5. Gotchas
1. **Shadowed Base Members**: Multiple members use the `new` keyword to shadow base class implementations (`PropertyChanged`, `OnPropertyChanged`, `IsBusy`, `IsDirty`, `ConfirmationRequest`, `Model`). This may cause unexpected behavior if consumers interact through base class references.
2. **Code Duplication**: `Subscribe()`, `SubscribeDataSelect()`, and `SubscribeResult()` have nearly identical implementations. The only difference is that `Subscribe()` additionally subscribes to `TestModificationChangedEvent`, but the handler `OnTestModificationChanged` is empty.
3. **Empty Handler**: `OnTestModificationChanged(ITestModificationModel obj)` has no implementation—potential tech debt or placeholder.
4. **Concrete Type Casting**: The code directly casts to `GraphView` and `TestDataSeriesView` concrete types, breaking the abstraction provided by interfaces. This creates tight coupling and could cause runtime failures if different implementations are registered.
5. **Unused Private Field**: `Model` property is declared but never used (suppressed by `// ReSharper disable NotAccessedField.Local`).
6. **Hardcoded Strings**: Chart type comparison uses literal strings (`"DataSelect"`, `"Graph"`) without constants, risking typos.
7. **Thread Affinity**: `GraphChannelsReadCompletedNotification` and `GraphChannelReadCalcProgressChangedEvent` are explicitly subscribed with `ThreadOption.UIThread`, indicating UI updates must occur on the dispatcher thread.

View File

@@ -0,0 +1,149 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/GraphListModule.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/ExportGraphListModule.cs
generated_at: "2026-04-16T11:04:41.132033+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "267c5c22d55f0847"
---
# Documentation: GraphList and ExportGraphList Modules
## 1. Purpose
This documentation covers two Prism modules within the DTS Viewer application: `GraphListModule` and `ExportGraphListModule`. Both modules follow an identical architectural pattern for registering views and view-models with the Unity dependency injection container. They provide assembly-level metadata (name, image, group, and region) via custom attributes, enabling the main application shell to discover and display these components as available modules. The `GraphListModule` provides the primary graph list visualization, while `ExportGraphListModule` appears to provide an export-oriented variant of the same functionality.
---
## 2. Public Interface
### GraphListModule Class
**Namespace:** `DTS.Viewer.GraphList`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `GraphListModule(IUnityContainer unityContainer)` | Accepts an injected Unity container instance and stores it in `_unityContainer`. |
| `RegisterTypes` | `void RegisterTypes(IContainerRegistry containerRegistry)` | Calls `Initialize()` to register types with the container. |
| `OnInitialized` | `void OnInitialized(IContainerProvider containerProvider)` | Empty implementation (no post-initialization logic). |
| `Initialize` | `void Initialize()` | Registers `IGraphMainView``GraphMainView` and `IGraphMainViewModel``GraphMainViewModel` with Unity. |
### GraphListNameAttribute Class
**Namespace:** `DTS.Viewer.GraphList`
**Base Class:** `TextAttribute`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `GraphListNameAttribute()` | Default constructor; initializes `_assemblyName` to `AssemblyNames.GraphList.ToString()`. |
| Constructor | `GraphListNameAttribute(string s)` | Overloaded constructor; parameter `s` is unused. |
| `AssemblyName` | `string AssemblyName { get; }` | Returns `_assemblyName`. |
| `GetAttributeType` | `Type GetAttributeType()` | Returns `typeof(TextAttribute)`. |
| `GetAssemblyName` | `string GetAssemblyName()` | Returns `AssemblyName`. |
### GraphListImageAttribute Class
**Namespace:** `DTS.Viewer.GraphList`
**Base Class:** `ImageAttribute`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `GraphListImageAttribute()` | Initializes `_img` via `AssemblyInfo.GetImage()`. |
| Constructor | `GraphListImageAttribute(string s)` | Parameter `s` is unused; initializes `_img`. |
| `AssemblyImage` | `BitmapImage AssemblyImage { get; }` | Lazy-loads image via `AssemblyInfo.GetImage(AssemblyNames.GraphList.ToString())`. |
| `AssemblyName` | `string AssemblyName { get; }` | Returns `AssemblyNames.GraphList.ToString()`. |
| `AssemblyGroup` | `string AssemblyGroup { get; }` | Returns `eAssemblyGroups.Viewer.ToString()`. |
| `AssemblyRegion` | `eAssemblyRegion AssemblyRegion { get; }` | Returns `eAssemblyRegion.GraphListRegion`. |
| `GetAttributeType` | `Type GetAttributeType()` | Returns `typeof(ImageAttribute)`. |
| `GetAssemblyImage` | `BitmapImage GetAssemblyImage()` | Returns `AssemblyImage`. |
| `GetAssemblyName` | `string GetAssemblyName()` | Returns `AssemblyName`. |
| `GetAssemblyGroup` | `string GetAssemblyGroup()` | Returns `AssemblyGroup`. |
| `GetAssemblyRegion` | `eAssemblyRegion GetAssemblyRegion()` | Returns `AssemblyRegion`. |
---
### ExportGraphListModule Class
**Namespace:** `DTS.Viewer.Export`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `ExportGraphListModule(IUnityContainer unityContainer)` | Accepts an injected Unity container instance. |
| `RegisterTypes` | `void RegisterTypes(IContainerRegistry containerRegistry)` | Calls `Initialize()`. |
| `OnInitialized` | `void OnInitialized(IContainerProvider containerProvider)` | Empty implementation. |
| `Initialize` | `void Initialize()` | Registers `IExportGraphMainView``ExportGraphMainView` and `IExportGraphMainViewModel``ExportGraphMainViewModel`. |
### ExportGraphListNameAttribute Class
**Namespace:** `DTS.Viewer.Export`
**Base Class:** `TextAttribute`
Identical structure to `GraphListNameAttribute`, returning `AssemblyNames.GraphList.ToString()`.
### ExportGraphListImageAttribute Class
**Namespace:** `DTS.Viewer.Export`
**Base Class:** `ImageAttribute`
Identical structure to `GraphListImageAttribute`, with the same values for `AssemblyName`, `AssemblyGroup`, and `AssemblyRegion`.
---
## 3. Invariants
1. **Constructor Injection Required:** Both modules require a non-null `IUnityContainer` instance to be injected at construction time. The container is stored but never null-checked.
2. **Single Instance per Assembly:** Both `[GraphListNameAttribute]` and `[GraphListImageAttribute]` (and their Export variants) are decorated with `AllowMultiple = false`, enforcing exactly one instance per assembly.
3. **Registration is Non-Singleton:** Both modules use `RegisterType<Interface, Implementation>()` without specifying a container-controlled lifetime, meaning each resolution creates a new instance (transient lifestyle).
4. **Initialize Called from RegisterTypes:** The `Initialize()` method is explicitly called within `RegisterTypes()`, not `OnInitialized()`. This ordering is intentional per Prism's module lifecycle.
5. **Fixed Assembly Metadata:**
- Both modules return `AssemblyNames.GraphList.ToString()` as their assembly name.
- Both return `eAssemblyGroups.Viewer.ToString()` as their group.
- Both return `eAssemblyRegion.GraphListRegion` as their region.
---
## 4. Dependencies
### External Dependencies (Imports)
| Namespace | Purpose |
|-----------|---------|
| `System` | Core .NET types (`Type`, `AttributeUsage`, `AttributeTargets`). |
| `System.Windows.Media.Imaging` | `BitmapImage` for assembly imagery. |
| `Prism.Ioc` | `IContainerProvider`, `IContainerRegistry` for Prism DI abstraction. |
| `Prism.Modularity` | `IModule`, `ModuleAttribute` for modular composition. |
| `Unity` | `IUnityContainer` for Unity-specific DI operations. |
### Internal Dependencies (Inferred)
| Namespace | Usage |
|-----------|-------|
| `DTS.Common` | `AssemblyNames` enum, `eAssemblyGroups` enum, `eAssemblyRegion` enum, `AssemblyInfo` static class. |
| `DTS.Common.Interface` | `TextAttribute`, `ImageAttribute` base classes. |
| `DTS.Viewer.GraphList` (local) | `GraphMainView`, `GraphMainViewModel`, `IGraphMainView`, `IGraphMainViewModel`. |
| `DTS.Viewer.Export` (local) | `ExportGraphMainView`, `ExportGraphMainViewModel`, `IExportGraphMainView`, `IExportGraphMainViewModel`. |
### Consumers
Unknown from source alone. The modules are discovered and loaded by a Prism-based shell application that scans for `IModule` implementations and assembly attributes.
---
## 5. Gotchas
1. **Duplicate Assembly Name Values:** Both `GraphListNameAttribute` and `ExportGraphListNameAttribute` return `AssemblyNames.GraphList.ToString()`. This may cause ambiguity if the shell application uses assembly name as a unique identifier. It is unclear whether this is intentional (shared identity) or a copy-paste oversight.
2. **Duplicate Region Assignment:** Both modules declare `eAssemblyRegion.GraphListRegion`. If the shell uses region-based navigation, both views may attempt to load into the same region, potentially causing conflicts or overwrites.
3. **Redundant Image Initialization:** In `GraphListImageAttribute` and `ExportGraphListImageAttribute`, the `_img` field is assigned in both the constructor and the `AssemblyImage` getter. The getter reassigns `_img` on every access, defeating the purpose of the constructor initialization.
4. **Unused Constructor Parameter:** Both attribute classes accept a `string s` parameter in an overloaded constructor but never use it. The ReSharper suppression comment `// ReSharper disable UnusedParameter.Local` acknowledges this but does not explain the design rationale.
5. **Empty OnInitialized:** Both modules leave `OnInitialized()` empty. If module initialization logic is expected here, it will not execute. The actual registration happens in `RegisterTypes()``Initialize()`.
6. **No Lifetime Management:** The `RegisterType` calls do not specify `ContainerControlledLifetimeManager`, meaning views and view-models are transient. If singleton behavior is expected (as suggested by the comment "Register View & View-Model with Unity dependency injection container as a singleton"), the implementation does not match the intent.

View File

@@ -0,0 +1,104 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/Classes/VirtualToggleButton.cs
generated_at: "2026-04-16T11:10:12.391241+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "001b39a3411ec3ba"
---
# Documentation: VirtualToggleButton.cs
## 1. Purpose
`VirtualToggleButton` is a static utility class that provides attached dependency properties to imbue any WPF element with toggle button behavior without requiring inheritance from `ToggleButton`. It enables elements to respond to mouse clicks and keyboard input (Space/Enter) to toggle between checked/unchecked/indeterminate states, and raises the corresponding routed events. This is useful for templated controls or custom elements that need toggle semantics without the overhead of full `ToggleButton` derivation.
---
## 2. Public Interface
### Attached Properties
| Property | Type | Default | Metadata Flags |
|----------|------|---------|----------------|
| `IsLockedProperty` | `Nullable<bool>` | `false` | `BindsTwoWayByDefault`, `Journal` |
| `IsThreeStateProperty` | `bool` | `false` | None |
| `IsVirtualToggleButtonProperty` | `bool` | `false` | None |
### Public Methods
#### `GetIsLocked(DependencyObject d) -> Nullable<bool>`
Retrieves the current locked/checked state of the target element.
#### `SetIsLocked(DependencyObject d, Nullable<bool> value)`
Sets the locked/checked state. Setting to `true` raises `ToggleButton.CheckedEvent`; `false` raises `ToggleButton.UncheckedEvent`; `null` raises `ToggleButton.IndeterminateEvent`.
#### `GetIsThreeState(DependencyObject d) -> bool`
Returns whether the target supports three-state behavior (true/false/null).
#### `SetIsThreeState(DependencyObject d, bool value)`
Enables or disables three-state mode. When `true`, `IsLocked` can be set to `null` as a third state.
#### `GetIsVirtualToggleButton(DependencyObject d) -> bool`
Returns whether the target is currently acting as a virtual toggle button.
#### `SetIsVirtualToggleButton(DependencyObject d, bool value)`
When set to `true`, attaches `MouseLeftButtonDown` and `KeyDown` handlers to the target (must implement `IInputElement`). When set to `false`, detaches these handlers.
### Internal Methods
#### `RaiseCheckedEvent(UIElement target) -> RoutedEventArgs`
Raises `ToggleButton.CheckedEvent` on the target element. Returns `null` if target is null.
#### `RaiseUncheckedEvent(UIElement target) -> RoutedEventArgs`
Raises `ToggleButton.UncheckedEvent` on the target element. Returns `null` if target is null.
#### `RaiseIndeterminateEvent(UIElement target) -> RoutedEventArgs`
Raises `ToggleButton.IndeterminateEvent` on the target element. Returns `null` if target is null.
---
## 3. Invariants
1. **Two-way binding by default**: `IsLockedProperty` is registered with `BindsTwoWayByDefault`, so bindings will update the source automatically.
2. **Event attachment requirement**: `IsVirtualToggleButton` only attaches event handlers if the target implements `IInputElement`. Non-`IInputElement` targets are silently ignored.
3. **Event raising requirement**: `RaiseEvent()` only works for targets that are either `UIElement` or `ContentElement`. Other `DependencyObject` types will not raise events.
4. **Toggle cycle behavior**:
- When `IsThreeState` is `false`: toggles between `true` and `false` only.
- When `IsThreeState` is `true`: cycles through `false``true``null``false`.
5. **Keyboard handling constraints**:
- Space key is ignored when Alt modifier is present (to avoid interfering with system menu).
- Enter key only triggers toggle if `KeyboardNavigation.AcceptsReturnProperty` is `true` on the sender.
6. **Event source filtering**: `OnKeyDown` only processes events where `e.OriginalSource == sender`, preventing handling of bubbled events from child elements.
---
## 4. Dependencies
### This module depends on:
- `System` (core types)
- `System.Windows` (`DependencyObject`, `DependencyProperty`, `FrameworkPropertyMetadata`, `UIElement`, `ContentElement`, `RoutedEventArgs`, `IInputElement`)
- `System.Windows.Controls.Primitives` (`ToggleButton` - for `CheckedEvent`, `UncheckedEvent`, `IndeterminateEvent`)
- `System.Windows.Input` (`Key`, `KeyEventArgs`, `Keyboard`, `KeyboardNavigation`, `ModifierKeys`, `MouseButtonEventArgs`)
### Consumers:
- Unclear from source alone. Any XAML or code in the `DTS.Viewer.GraphList` namespace or referencing it may use these attached properties.
---
## 5. Gotchas
1. **Misleading XML documentation**: The XML comments for `IsLocked` state "indicates whether the toggle button is checked" — this appears to be copy-pasted from a standard `ToggleButton` implementation. The property is named `IsLocked`, not `IsChecked`, which may indicate domain-specific semantics (e.g., locking a graph item vs. selecting it).
2. **Type mismatch between event raising methods**: `RaiseCheckedEvent`, `RaiseUncheckedEvent`, and `RaiseIndeterminateEvent` accept only `UIElement`, but the private `RaiseEvent` helper supports both `UIElement` and `ContentElement`. If a `ContentElement` has `IsLocked` set, the change handler will attempt to raise events on it via `RaiseEvent`, but the public `RaiseXxxEvent` methods cannot be called with `ContentElement` directly.
3. **Null return from event methods**: The `RaiseXxxEvent` methods return `null` when the target is null, but they do not throw. Callers should check for null if they intend to use the returned `RoutedEventArgs`.
4. **Local variable shadows property name**: In `UpdateIsLocked()`, the local variable is named `IsLocked`, which shadows the property accessor method naming convention. This is legal but could cause confusion during debugging.
5. **No validation of IsThreeState consistency**: Setting `IsLocked` to `null` is always possible regardless of `IsThreeState` value. The `IsThreeState` property only affects toggle behavior in `UpdateIsLocked()`, not direct programmatic assignment.

View File

@@ -0,0 +1,117 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/Model/GraphPropertyObject.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/Model/GraphObject.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/Model/TreeViewChannels.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/Model/TreeViewIds.cs
generated_at: "2026-04-16T11:11:47.054703+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "47d9a78e7853eabc"
---
# Documentation: DTS.Viewer.GraphList.Models
## 1. Purpose
This module provides the data model classes for the Graph List functionality within the DTS Viewer application. It defines the structure for individual graph objects (`GraphObject`, `GraphPropertyObject`) and the hierarchical view models required to populate WPF TreeView controls (`TreeViewChannels`, `TreeViewIds`). The module bridges raw data with UI-specific behaviors, implementing `INotifyPropertyChanged` for data binding and handling complex selection logic for channel and event navigation.
## 2. Public Interface
### Class: `GraphPropertyObject`
Located in `DTS.Viewer.GraphList.Model`. A POCO-style class decorated with attributes for the Xceed WPF Toolkit PropertyGrid.
* **`GraphPropertyObject()`**: Default constructor.
* **`int Id`**: Read-only property categorized under "Information".
* **`string Name`**: Read-only property categorized under "Information".
* **`string Description`**: Read-only property categorized under "Information".
* **`string Filter`**: Categorized under "Parameters"; uses `ItemsSource(typeof(CFCFilterItemSource))`.
* **`string DataFlag`**: Categorized under "Parameters".
* **`double ShiftT0`**: Categorized under "Parameters".
* **`double EuMultiplier`**: Categorized under "Parameters".
* **`double EuOffset`**: Categorized under "Parameters".
### Class: `GraphObject`
Located in `DTS.Viewer.GraphList.Model`. Implements `IBaseClass`. Represents a single graph entity containing both data and display parameters.
* **`GraphObject()`**: Constructor that calls `LoadGraphs()`.
* **`int RecordId`**: Gets or sets the record ID; notifies property change.
* **`int Id`**: Gets or sets the ID; synchronizes with `Property.Id`.
* **`string Name`**: Gets or sets the name; synchronizes with `Property.Name`.
* **`string Description`**: Gets or sets the description; synchronizes with `Property.Description`.
* **`CFCFilter Filter`**: Gets or sets the filter; synchronizes with `Property.Filter` (converted to string).
* **`string DataFlag`**: Gets or sets the data flag; synchronizes with `Property.DataFlag`.
* **`double ShiftT0`**: Gets or sets the T0 shift; synchronizes with `Property.ShiftT0`.
* **`double EuMultiplier`**: Gets or sets the EU multiplier; synchronizes with `Property.EuMultiplier`.
* **`double EuOffset`**: Gets or sets the EU offset; synchronizes with `Property.EuOffset`.
* **`List<double> Data`**: Gets or sets the list of data points.
* **`bool Visable`**: Gets or sets the visibility state.
* **`GraphPropertyObject Property`**: Gets or sets the internal property object wrapper.
* **`event PropertyChangedEventHandler PropertyChanged`**: Event for property change notification.
* **`void OnPropertyChanged(string propertyName)`**: Invokes the `PropertyChanged` event.
### Class: `TreeViewChannels`
Located in `DTS.Viewer.GraphList`. Implements `IBaseModel`. Root node for binding a channel-based TreeView.
* **`string Name`**: Gets or sets the node name.
* **`ObservableCollection<TestGroup> Groups`**: Gets or sets the child groups; updates `GroupsCount` on set.
* **`int GroupsCount`**: Gets or sets the count of groups.
* **`string Path`**: Gets or sets the path.
* **`bool IsSaved`**: Getter only (read-only).
* **`bool IsExpanded`**: Gets or sets the expanded state of the TreeView node.
* **`bool IsSelected`**: Gets or sets the selected state.
### Class: `TestGroup`
Located in `DTS.Viewer.GraphList`. Child node for `TreeViewChannels`.
* **`IBaseViewModel Parent`**: Gets or sets the parent ViewModel.
* **`bool IsLocked`**: Gets or sets the locked state; calls `((IGraphMainViewModel)Parent).AddLockedGroupChannels(...)` on set.
* **`bool IsSelected`**: Gets or sets the selected state; calls `((IGraphMainViewModel)Parent).AddSelectedGroupChannels(...)` on set. Ignores selection if `Name` starts with "Test Channels" or "Calculated Channels".
* **`bool CanLock`**: Controls whether the item can be locked.
* **`ObservableCollection<ITestChannel> Channels`**: Gets or sets the collection of channels.
* **Other Properties**: `Path`, `DTSFile`, `IsGraph`, `IsExpanded`, `TestName`, `Name`, `DisplayName`, `ChannelCount`.
### Class: `TreeViewIds`
Located in `DTS.Viewer.GraphList`. Implements `IBaseModel`. Root node for binding an ID/Event-based TreeView.
* **`IBaseViewModel Parent`**: Gets or sets the parent ViewModel.
* **`int TreeIndex`**: Gets or sets the index of this tree node.
* **`ObservableCollection<ITestEvent> Events`**: Gets or sets child events.
* **`bool IsSelected`**: Gets or sets the selected state; manages cascading selection to children via `SetChildNodes`.
* **`void SetChildNodes(bool isSelected)`**: Iterates through `Events` and sets their `IsSelected` property.
* **`static void SetIsItemSelected(UIElement element, bool value)`**: Attached property setter for `IsItemSelectedProperty`.
### Class: `TestEvent`
Located in `DTS.Viewer.GraphList`. Implements `ITestEvent`. Child node for `TreeViewIds`.
* **`bool IsSelected`**: Complex setter that handles Shift/Ctrl key logic for multi-selection. Interacts with `IExportGraphMainViewModel` to manage selection lists (`AddToSelectedEvents`, `RemoveFromSelectedEvents`).
* **`bool IsLocked`**: Gets or sets locked state; calls `((IExportGraphMainViewModel)parent).AddLockedEvents(...)` on set.
* **Other Properties**: `Path`, `Parent`, `IsGraph`, `IsExpanded`, `CanLock`, `TestName`, `Name`, `TestSetupName`, `TestItem`, `DTSFile`, `DataType`, `Events`, `TestId`, `TreeIndex`.
## 3. Invariants
* **Synchronization**: When `GraphObject.Id`, `Name`, `Description`, `Filter`, `DataFlag`, `ShiftT0`, `EuMultiplier`, or `EuOffset` are set, the corresponding property on the internal `GraphPropertyObject` instance (accessed via `Property`) must be updated immediately.
* **Type Conversion**: `GraphObject.Filter` is of type `CFCFilter` (enum), but it is stored as a `string` in `GraphPropertyObject.Filter`.
* **Collection Counts**: Setting `TreeViewChannels.Groups` automatically updates `GroupsCount`. Setting `TestGroup.Channels` automatically updates `ChannelCount`. Setting `TreeViewIds.Events` automatically updates `EventCount`.
* **Parent Interface Requirements**:
* `TestGroup` requires its `Parent` to be castable to `IGraphMainViewModel`.
* `TreeViewIds` and `TestEvent` require their `Parent` to be castable to `IExportGraphMainViewModel`.
## 4. Dependencies
**Internal Dependencies (Inferred from imports):**
* `DTS.Common`: Uses `CFCFilter` enum and `CFCFilterItemSource`.
* `DTS.Common.Base`: Uses `IBaseClass`, `IBaseModel`.
* `DTS.Common.Interface`: Uses `IBaseViewModel`, `ITestChannel`, `ITestEvent`, `IGraphMainViewModel`, `IExportGraphMainViewModel`.
**External Dependencies:**
* `Xceed.Wpf.Toolkit.PropertyGrid.Attributes`: Used for `Category`, `DisplayName`, `ReadOnly`, `Description`, and `ItemsSource` attributes in `GraphPropertyObject`.
* `System.Windows`: Used for `DependencyProperty`, `UIElement`, `Input.Keyboard`, `Controls.ItemsControl`.
## 5. Gotchas
* **Typo in Property Name**: `GraphObject.Visable` appears to be a typo for "Visible".
* **Silent Failures in Selection Logic**: In `TreeViewIds.IsSelected`, if `Parent` is null or not of type `IExportGraphMainViewModel`, the setter returns early without setting the backing field or notifying property change.
* **Complex Setter Logic (Side Effects)**:
* Setting `TestGroup.IsSelected` or `TestEvent.IsSelected` triggers logic in the parent ViewModel that modifies global state (selection lists).
* `TestEvent.IsSelected` reads static keyboard state (`Keyboard.IsKeyDown`) directly within the property setter. This ties the model tightly to the UI input state and can cause unpredictable behavior if the property is set programmatically rather than via user interaction.
* **Hardcoded String Comparisons

View File

@@ -0,0 +1,50 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T11:10:44.942572+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "af860c5bc7afa07c"
---
# Documentation: DTS.Viewer.GraphList Assembly Metadata
## 1. Purpose
This file provides assembly-level metadata configuration for the `DTS.Viewer.GraphList` module (compiled as `Graph.dll`). It defines version information, copyright details, and COM visibility settings using .NET attributes. This module exists to embed standard manifest information into the compiled assembly, ensuring proper identification and interaction within the larger DTS Viewer application ecosystem.
## 2. Public Interface
This file does not contain public classes, methods, or functions. It strictly applies assembly-level attributes.
**Defined Attributes:**
* **`AssemblyTitle`**: Set to `"Graph"`.
* **`AssemblyDescription`**: Set to an empty string.
* **`AssemblyConfiguration`**: Set to an empty string.
* **`AssemblyCompany`**: Set to an empty string.
* **`AssemblyProduct`**: Set to `"Graph"`.
* **`AssemblyCopyright`**: Set to `"Copyright © 2017"`.
* **`AssemblyTrademark`**: Set to an empty string.
* **`AssemblyCulture`**: Set to an empty string (indicates a culture-neutral assembly).
* **`ComVisible`**: Set to `false`. Prevents types within this assembly from being visible to COM components.
* **`Guid`**: Set to `"61261c58-c32e-4dea-a87a-d7f956f28b4d"`. serves as the ID for the type library if exposed to COM.
* **`AssemblyVersion`**: Set to `"1.0.0.0"`.
* **`AssemblyFileVersion`**: Set to `"1.0.0.0"`.
## 3. Invariants
* **Versioning:** The assembly version and file version are explicitly synchronized at `1.0.0.0`.
* **COM Visibility:** Types in this assembly are explicitly hidden from COM components by default (`ComVisible(false)`).
* **Culture:** The assembly is strictly culture-neutral (`AssemblyCulture("")`).
## 4. Dependencies
**Internal Dependencies (Imports):**
* `System.Reflection`
* `System.Runtime.CompilerServices`
* `System.Runtime.InteropServices`
**External Dependencies:**
* None identified from source alone. This file relies solely on standard .NET Framework libraries.
## 5. Gotchas
* **Naming Inconsistency:** The `AssemblyTitle` and `AssemblyProduct` attributes are set to `"Graph"`, whereas the project directory implies the module name is `DTS.Viewer.GraphList`. This discrepancy suggests the metadata may not have been updated to match the project namespace, or the module is colloquially referred to as "Graph" internally.
* **Sparse Metadata:** The `AssemblyDescription`, `AssemblyCompany`, and `AssemblyConfiguration` fields are empty strings, which may result in sparse metadata visibility in file properties or deployment logs.
* **Hardcoded Version:** The version is hardcoded to `1.0.0.0`. If the build system relies on auto-incrementing versions (e.g., via MSBuild or CI/CD pipelines), this file may need to be auto-generated or ignored during the build process to reflect accurate build numbers.

View File

@@ -0,0 +1,71 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/View/ExportGraphMainView.xaml.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/View/GraphMainView.xaml.cs
generated_at: "2026-04-16T11:11:08.452052+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "e0305153f9f5be9f"
---
# Documentation: DTS.Viewer.GraphList Views
## 1. Purpose
This module contains WPF code-behind files for two graph-related views in the DTS Viewer application: `ExportGraphMainView` and `GraphMainView`. Both views implement corresponding interfaces from `DTS.Common.Interface` and provide interaction logic for their respective XAML counterparts. Their primary runtime behavior is to intercept and suppress the `ApplicationCommands.Undo` command, preventing undo operations from propagating further in the command routing system.
---
## 2. Public Interface
### `ExportGraphMainView` (class)
**Implements:** `IExportGraphMainView`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `public ExportGraphMainView()` | Initializes the XAML component via `InitializeComponent()` and registers a `CommandBinding` for `ApplicationCommands.Undo`. Both the Execute and CanExecute handlers set `e.Handled = true` without performing any other action. |
---
### `GraphMainView` (class)
**Implements:** `IGraphMainView`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `public GraphMainView()` | Initializes the XAML component via `InitializeComponent()` and registers a `CommandBinding` for `ApplicationCommands.Undo`. Both the Execute and CanExecute handlers set `e.Handled = true` without performing any other action. |
**Note:** The `GraphMainView` class contains commented-out code referencing:
- `root.IsChecked` (presumably a UI element)
- `TvTestChannels.Focus()` (a method call)
- A commented-out method `SetTvFocus()`
---
## 3. Invariants
1. **Partial Class Structure:** Both `ExportGraphMainView` and `GraphMainView` are declared as `partial` classes, implying the existence of XAML-generated counterparts that must be present at compile time.
2. **Undo Command Suppression:** Both views guarantee that `ApplicationCommands.Undo` will always be marked as handled (`e.Handled = true`) in both Execute and CanExecute handlers, effectively disabling undo functionality within these views.
3. **Interface Implementation:** Each view must implement its respective interface (`IExportGraphMainView` or `IGraphMainView`) from `DTS.Common.Interface`.
---
## 4. Dependencies
### This module depends on:
- `System.Windows.Input` — Provides `CommandBinding` and `ApplicationCommands`
- `DTS.Common.Interface` — Provides `IExportGraphMainView` and `IGraphMainView` interfaces
### What depends on this module:
- **Not determinable from source alone.** The views are likely instantiated by a view factory, dependency injection container, or referenced by view models in the `DTS.Viewer.GraphList` module or a higher-level orchestration layer.
---
## 5. Gotchas
1. **No-op Undo Handlers:** Both views register command bindings for `ApplicationCommands.Undo` that do nothing except mark the event as handled. This effectively disables undo functionality without providing alternative behavior. The intent is unclear from source alone—this may be intentional suppression or placeholder code.
2. **Commented-Out Code in `GraphMainView`:** The presence of commented-out references to `root.IsChecked`, `TvTestChannels.Focus()`, and the `SetTvFocus()` method suggests incomplete or removed functionality. The original purpose of these members cannot be determined from source alone.
3. **Namespace Suppression:** Both files include `// ReSharper disable CheckNamespace`, indicating the namespace `DTS.Viewer.GraphList` may not match the folder structure (`DTS.Viewer.Modules/DTS.Viewer.GraphList/View/`). This could cause confusion when navigating the codebase.

View File

@@ -0,0 +1,93 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/ViewModel/GraphMainViewModel.cs
generated_at: "2026-04-16T11:10:28.732851+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "09077834bf97663d"
---
# Documentation: GraphMainViewModel.cs
## 1. Purpose
The `GraphMainViewModel` class acts as the presentation logic controller for the Graph List module within the DTS Viewer application. It is responsible for managing the lifecycle of test channels—retrieving them from test summaries, organizing them into a hierarchical tree structure (Test > Group > Channel), and handling user interactions for selecting or locking channels for visualization. It serves as a bridge between the data layer (test summaries, metadata) and the UI layer, publishing events to notify other parts of the system when channels are selected, locked, or cleared.
## 2. Public Interface
### Public Properties
* **`IFilterView FilterView`**: Gets the filter view instance associated with this ViewModel.
* **`IGraphMainView View`**: Gets or sets the associated view interface.
* **`IBaseViewModel Parent`**: Gets or sets the parent ViewModel (used to scope events and behavior).
* **`InteractionRequest<Notification> NotificationRequest`**: Used to raise notification dialogs.
* **`InteractionRequest<Confirmation> ConfirmationRequest`**: Used to raise confirmation dialogs (hides base member).
* **`List<ITestChannel> LockedChannelList`**: Gets or sets the list of channels currently locked by the user.
* **`List<ITestChannel> SelectedChannelList`**: Gets or sets the list of channels currently selected by the user.
* **`ObservableCollection<ITestChannel> ChannelList`**: The master list of all available channels.
* **`ObservableCollection<ITestChannel> FilteredChannelList`**: The list of channels displayed to the user after filtering is applied.
* **`ObservableCollection<TreeViewChannels> TestChannelsTree`**: The hierarchical structure of channels bound to the UI TreeView.
* **`bool IsFilterEnabled`**: Indicates if the filter UI should be enabled (true if `ChannelList` has items).
* **`string SelectedGroupName`**: The name of the currently selected group.
* **`string LockedGroupName`**: The name of the currently locked group.
* **`bool TestModified`**: Indicates if the underlying test data has been modified.
### Public Methods
* **`void Initialize()`**: Overrides base method; currently empty.
* **`void Initialize(object parameter)`**: Initializes the ViewModel, sets the `Parent`, determines if locked-only mode is active (if Parent is `IPSDReportMainViewModel`), initializes the filter view, and subscribes to events.
* **`void PublishSelectedChannels()`**: Publishes the `GraphSelectedChannelsNotification` and `GraphSelectedChannelCountNotification` events containing the current lists of locked and/or selected channels.
* **`void AddLockedGroupChannels(string testName, string groupName, List<ITestChannel> channels, bool isLocked)`**: Adds or removes a group of channels to/from the `LockedChannelList`.
* **`void AddLockedChannel(ITestChannel channel, bool isLocked)`**: Adds or removes a single channel to/from the `LockedChannelList`.
* **`void AddSelectedGroupChannels(string groupName, List<ITestChannel> channels)`**: Selects a specific group of channels, resetting previous selections.
* **`void AddSelectedGroup(TestGroup group)`**: Marks a specific `TestGroup` as selected.
* **`void AddSelectedChannel(ITestChannel channel, bool reset)`**: Adds a single channel to the `SelectedChannelList`. If `reset` is true, previous selections are cleared.
* **`void AddSelectedChannel(ITestChannel channel)`**: Overload that resets previous selections before adding the new channel.
* **`void OnFilterChanged(FilterParameterArgs args)`**: Filters the `ChannelList` based on a string parameter and updates `FilteredChannelList`.
* **`void Activated()`**: Overrides base method; publishes an empty `FilterParameterChangedEvent` to reset the filter.
## 3. Invariants
* **Maximum Locked Channels**: The system enforces a hard limit of **8** locked channels (`MAX_LOCKED_CHANNELS`). The `UpdateChannelLocks` method disables the ability to lock further channels once this limit is reached.
* **Mutual Exclusivity**: A channel cannot be simultaneously in the `SelectedChannelList` and `LockedChannelList`. Locking a channel removes it from the selected list.
* **Color Assignment**: Channels are assigned colors from a fixed palette (`_graphColors`). The `GetNextColor` method ensures colors are unique if available, or cycles through the palette if the channel count exceeds the color count.
* **Parent Scoping**: Event handlers (e.g., `OnTestSummaryChanged`) check if the event's `ParentVM` matches the ViewModel's `Parent` property to ensure the event is relevant to this specific instance.
* **Locked-Only Mode**: If the `Parent` is of type `IPSDReportMainViewModel`, the `_lockedOnly` flag is set to `true`. In this mode, `PublishSelectedChannels` only publishes locked channels, ignoring selected channels.
## 4. Dependencies
### External Dependencies
* **Prism**: `IEventAggregator`, `IRegionManager` (for event pub/sub and region navigation).
* **Unity**: `IUnityContainer` (for dependency resolution).
* **System.Windows.Media**: `Color`, `Colors` (for channel visualization).
### Internal Dependencies (Inferred)
* **DTS.Common.Interface**: `ITestChannel`, `ITestSummary`, `IGraphMainView`, `IFilterView`, `ITestModificationModel`.
* **DTS.Common.Events**: `TestSummaryChangeNotificationArg`, `GraphClearNotificationArg`, `FilterParameterArgs`, etc.
* **DTS.Common.Enums.Sensors**: `CalibrationBehaviors`, `IsoViewMode`.
* **DTS.Serialization**: Referenced via `Utils.SetChannelInfo` for lazy loading channel metadata.
### Events Consumed
* `RaiseNotification`
* `FilterParameterChangedEvent`
* `TestSummaryChangeNotification`
* `TestModificationChangedEvent`
* `CalibrationBehaviorSettingChangedEvent`
* `CalibrationBehaviorSettableInViewerChangedEvent`
* `ChannelCodesViewChangedEvent`
### Events Published
* `GraphClearNotification`
* `GraphLoadedCountNotification`
* `GraphSelectedChannelCountNotification`
* `GraphSelectedChannelsNotification`
* `BusyIndicatorChangeNotification`
* `FilterParameterChangedEvent`
## 5. Gotchas
* **Member Hiding**: The class uses the `new` keyword to hide base members (`ConfirmationRequest`, `PropertyChanged`, `OnPropertyChanged`, `IsBusy`, `IsDirty`). Accessing these via a base class reference will bypass the logic defined in `GraphMainViewModel`.
* **Explicit GC Collection**: The `CleanSelection` method explicitly calls `GC.Collect()`. This is generally discouraged in .NET development and could introduce performance pauses.
* **Lazy Loading Side Effect**: Inside `OnTestSummaryChanged`, there is a check `if (l.Channels.FirstOrDefault() == null)`. If true, it triggers `Utils.SetChannelInfo`, which modifies `l.Channels`, `l.Graphs`, and `l.CalculatedChannels` in place. This suggests the data object passed via the event is mutable and potentially incomplete prior to this handler executing.
* **Calibration Logic Mutation**: The `OnTestSummaryChanged` method modifies the `tsChannels` list (removing items or modifying `ChannelDescriptionString`) based on `calibrationBehaviorSetting`. This alters the data before it is displayed, specifically handling Linear vs. NonLinear calibration duplicates.
* **Dead Code / Empty Handlers**:
* The subscription to `GraphChannelsReadCompletedNotification` is commented out with the note "It does not work".
* Event handlers `TestChannelsTree_PropertyChanged` and `GraphList_PropertyChanged` contain empty `if` blocks (e.g., `if (e.PropertyName != "TestChannelsTree") { }`), which appears to be incomplete logic.
* `OnCalibrationBehaviorSettableInViewerChanged` is subscribed but has an empty implementation body.

View File

@@ -0,0 +1,86 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Navigation/NavigationModule.cs
generated_at: "2026-04-16T11:07:35.667287+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "b8a48119ee42a5bd"
---
# Documentation: DTS.Viewer.Navigation
## 1. Purpose
This module serves as the entry point for the Navigation component within the DTS Viewer application. It is a Prism Module (`NavigationModule`) responsible for registering the Navigation view and view model with the Unity dependency injection container. Additionally, it defines assembly-level attributes (`NavigationPropertiesNameAttribute`, `NavigationPropertiesImageAttribute`) that expose metadata—such as the assembly name, icon, and region assignment—to the broader application, likely for dynamic UI generation or module listing in the main shell.
## 2. Public Interface
### `NavigationModule`
The main Prism module class responsible for DI registration.
* **`NavigationModule(IUnityContainer unityContainer)`**
* Constructor that accepts an `IUnityContainer` instance via dependency injection and stores it in a private readonly field.
* **`void RegisterTypes(IContainerRegistry containerRegistry)`**
* Implements `IModule.RegisterTypes`. Calls the private `Initialize()` method to perform type registration.
* **`void OnInitialized(IContainerProvider containerProvider)`**
* Implements `IModule.OnInitialized`. Currently contains an empty implementation block.
### `NavigationPropertiesNameAttribute`
An assembly-level attribute extending `TextAttribute` used to expose the assembly name.
* **`NavigationPropertiesNameAttribute()`**
* Default constructor. Initializes the internal assembly name string.
* **`NavigationPropertiesNameAttribute(string s)`**
* Overloaded constructor accepting a string `s` (which appears to be ignored in the implementation).
* **`override string AssemblyName`**
* Property getter returning the string value of `AssemblyNames.Navigation`.
* **`override Type GetAttributeType()`**
* Returns `typeof(TextAttribute)`.
* **`override string GetAssemblyName()`**
* Returns the `AssemblyName` property value.
### `NavigationPropertiesImageAttribute`
An assembly-level attribute extending `ImageAttribute` used to expose visual metadata (image, group, region).
* **`NavigationPropertiesImageAttribute()`**
* Default constructor. Initializes the assembly image.
* **`NavigationPropertiesImageAttribute(string s)`**
* Overloaded constructor accepting a string `s` (ignored in implementation).
* **`override BitmapImage AssemblyImage`**
* Property getter that retrieves a `BitmapImage` via `AssemblyInfo.GetImage`.
* **`override string AssemblyName`**
* Returns `AssemblyNames.Navigation.ToString()`.
* **`override string AssemblyGroup`**
* Returns `eAssemblyGroups.Viewer.ToString()`.
* **`override eAssemblyRegion AssemblyRegion`**
* Returns `eAssemblyRegion.NavigationRegion`.
* **`override BitmapImage GetAssemblyImage()`**
* Returns the `AssemblyImage` property.
* **`override string GetAssemblyName()`**
* Returns the `AssemblyName` property.
* **`override eAssemblyRegion GetAssemblyRegion()`**
* Returns the `AssemblyRegion` property.
* **`override string GetAssemblyGroup()`**
* Returns the `AssemblyGroup` property.
## 3. Invariants
* **Module Name:** The `NavigationModule` is identified by the string `"NavigationProperties"` via the `[Module]` attribute.
* **Attribute Usage:** Both custom attributes are decorated with `[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]`, ensuring only one instance of each exists per assembly.
* **Type Registration:** The `INavigationView` interface is always mapped to the `NavigationView` class, and `INavigationViewModel` is mapped to `NavigationViewModel`.
* **Metadata Constants:** The `AssemblyName` is strictly derived from `AssemblyNames.Navigation`, the `AssemblyGroup` from `eAssemblyGroups.Viewer`, and the `AssemblyRegion` from `eAssemblyRegion.NavigationRegion`.
## 4. Dependencies
**Internal Dependencies (referenced but not defined in source):**
* `DTS.Common`: Likely contains `AssemblyNames`, `eAssemblyGroups`, `eAssemblyRegion`, and `AssemblyInfo`.
* `DTS.Common.Interface`: Defines `TextAttribute`, `ImageAttribute`, `INavigationView`, and `INavigationViewModel`.
* `DTS.Viewer.Navigation` (local namespace): Contains `NavigationView` and `NavigationViewModel` classes (referenced but not shown in source).
**External Frameworks:**
* `Prism.Ioc`, `Prism.Modularity`: For module definition and DI abstractions.
* `Unity`: `IUnityContainer` for specific dependency injection implementation.
* `System.Windows.Media.Imaging`: For `BitmapImage`.
## 5. Gotchas
* **Comment/Code Mismatch (Singleton vs. Transient):** The comment in `Initialize()` states: *"Register View & View-Model ... as a singleton."* However, the code uses `_unityContainer.RegisterType<...>()`. In Unity, `RegisterType` registers a transient mapping (new instance per resolve) by default. To register as a singleton, `ContainerControlledLifetimeManager` should be used. The code does not match the intent described in the comment.
* **Ignored Constructor Parameters:** Both attribute classes possess constructors taking a `string s`, but the parameter is never used inside the constructor body. The `_assemblyName` or `_img` fields are always populated using hardcoded `AssemblyNames.Navigation` lookups.
* **Side Effects in Property Getters:** The `AssemblyImage` property getter in `NavigationPropertiesImageAttribute` has a side effect: it assigns the private field `_img` before returning it (`_img = ...; return _img;`). This is non-standard property behavior and could lead to unnecessary object creation if the property is accessed frequently.
* **Mixed Container Usage:** The module uses `IUnityContainer` (passed via constructor) to register types inside `Initialize`, but the `RegisterTypes` method receives an `IContainerRegistry`. The code bridges this by ignoring the `IContainerRegistry` parameter and using the stored `_unityContainer` reference directly.

View File

@@ -0,0 +1,45 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Navigation/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T11:19:57.689390+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "24368b2aa50ace4f"
---
# Documentation: DTS.Viewer.Navigation Assembly Configuration
## 1. Purpose
This file provides assembly-level metadata and configuration for the `DTS.Viewer.Navigation` module. It exists to define the identity, versioning, and COM visibility settings for the compiled output (DLL) of this specific project within the larger DTS Viewer solution. It does not contain executable logic.
## 2. Public Interface
This file does not expose any public classes, methods, or functions. It applies the following assembly-level attributes:
* **`AssemblyTitle`**: Set to `"DTS.Viewer.Navigation"`.
* **`AssemblyDescription`**: Set to an empty string.
* **`AssemblyConfiguration`**: Set to an empty string.
* **`AssemblyCompany`**: Set to an empty string.
* **`AssemblyProduct`**: Set to `"DTS.Viewer.Navigation"`.
* **`AssemblyCopyright`**: Set to `"Copyright © 2017"`.
* **`AssemblyTrademark`**: Set to an empty string.
* **`AssemblyCulture`**: Set to an empty string.
* **`ComVisible`**: Set to `false`. This prevents types in this assembly from being visible to COM components.
* **`Guid`**: Set to `"237c6e9f-9118-4bec-a55a-e194232ac330"`. This acts as the ID for the type library if the assembly is exposed to COM.
* **`AssemblyVersion`**: Set to `"1.0.0.0"`.
* **`AssemblyFileVersion`**: Set to `"1.0.0.0"`.
## 3. Invariants
* **COM Visibility:** The assembly is explicitly marked with `ComVisible(false)`. Types within this assembly are not accessible to COM clients unless individual types are explicitly marked as visible.
* **Versioning:** Both the assembly version and file version are fixed at `1.0.0.0`. The automatic versioning wildcard syntax (e.g., `1.0.*`) is commented out and not active.
## 4. Dependencies
* **Internal Dependencies:**
* `System.Reflection`
* `System.Runtime.CompilerServices`
* `System.Runtime.InteropServices`
* **External Dependencies:** None identified from this source file alone. The module `DTS.Viewer.Navigation` is likely a component of the larger `DTS Viewer` application, but its specific internal dependencies cannot be determined from this file.
## 5. Gotchas
* **Missing Metadata:** The `AssemblyDescription`, `AssemblyConfiguration`, and `AssemblyCompany` attributes are present but contain empty strings. This may result in missing metadata in the compiled assembly properties.
* **Legacy Project Structure:** The existence of an explicit `AssemblyInfo.cs` file suggests this project uses the older .NET Framework SDK-style project format (pre-.NET Core/5+ style), which typically auto-generates this information in the `.csproj` file.
* **Static Versioning:** The version numbers are hardcoded to `1.0.0.0`. If continuous integration or automatic build numbering is required, the commented-out wildcard pattern or a build target override would be necessary.

View File

@@ -0,0 +1,66 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Navigation/View/NavigationItem.xaml.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Navigation/View/NavigationView.xaml.cs
generated_at: "2026-04-16T11:19:54.392457+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "e298dba7e9bc3e6c"
---
# Documentation: DTS.Viewer.Navigation Views
## 1. Purpose
This module provides WPF view components for the navigation subsystem of the DTS Viewer application. It contains two code-behind classes—`NavigationItem` and `NavigationView`—that serve as the presentation layer for navigation UI elements. These views are part of a modular architecture (`DTS.Viewer.Modules`) and implement framework-level interfaces to integrate with the broader application infrastructure. The actual UI layout and visual composition are defined in corresponding XAML files (not provided).
---
## 2. Public Interface
### `NavigationItem` (class)
**Namespace:** `DTS.Viewer.Navigation.View`
**Implements:** `IBaseView` (from `DTS.Common.Base`)
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `public NavigationItem()` | Default constructor. Calls `InitializeComponent()` to load the associated XAML layout. |
### `NavigationView` (class)
**Namespace:** `DTS.Viewer.Navigation`
**Implements:** `INavigationView` (from `DTS.Common.Interface`)
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `public NavigationView()` | Default constructor. Calls `InitializeComponent()` to load the associated XAML layout. |
---
## 3. Invariants
- Both classes are declared `partial`, implying a code-behind pattern where the XAML compiler generates additional class members.
- `InitializeComponent()` must be called in the constructor for each view; this is a WPF requirement for loading the compiled XAML resource.
- `NavigationItem` must always implement `IBaseView`.
- `NavigationView` must always implement `INavigationView`.
- The associated XAML files (`NavigationItem.xaml` and `NavigationView.xaml`) must exist and be properly linked as compiled resources.
---
## 4. Dependencies
### This module depends on:
- `DTS.Common.Base` — Provides `IBaseView` interface
- `DTS.Common.Interface` — Provides `INavigationView` interface
- WPF presentation framework (implicit via `InitializeComponent()` and `partial` class pattern)
### What depends on this module:
- **Cannot be determined from source alone.** No downstream consumers are visible in these files.
---
## 5. Gotchas
- **Interface contracts are unknown:** The requirements of `IBaseView` and `INavigationView` are not visible in the provided source. Developers must consult `DTS.Common.Base` and `DTS.Common.Interface` to understand expected members or behaviors.
- **All logic resides in XAML:** The code-behind files contain no business logic beyond initialization. Visual behavior, data bindings, and event handlers are defined in the corresponding `.xaml` files (not provided).
- **Namespace inconsistency:** `NavigationItem` resides in `DTS.Viewer.Navigation.View`, while `NavigationView` resides directly in `DTS.Viewer.Navigation`. This may be intentional (separating view models/views) or a historical quirk worth verifying.
- **No explicit DataContext assignment:** Neither constructor sets a DataContext, suggesting binding or view model injection occurs elsewhere (possibly in XAML or via an external framework).

View File

@@ -0,0 +1,92 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Navigation/ViewModel/NavigationViewModel.cs
generated_at: "2026-04-16T11:19:33.784254+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "17ac7f526470fc92"
---
# Documentation: NavigationViewModel
## 1. Purpose
`NavigationViewModel` is a ViewModel component responsible for managing the navigation UI region within the DTS Viewer application. It serves as a mediator between the `INavigationView` and the application's navigation system, handling notification and confirmation dialogs via Prism's interaction request patterns. The class inherits from `BaseViewModel<INavigationViewModel>` and implements `INavigationViewModel`, integrating with the Prism/Unity dependency injection and region management framework.
---
## 2. Public Interface
### Constructor
```csharp
public NavigationViewModel(INavigationView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
```
Initializes the navigation view model with its dependencies. Sets the view's `DataContext` to itself, creates `NotificationRequest` and `ConfirmationRequest` instances, and subscribes to the `RaiseNotification` event via the event aggregator.
### Properties
| Property | Signature | Description |
|----------|-----------|-------------|
| `NavigationView` | `INavigationView { get; private set; }` | Holds the associated navigation view instance. |
| `NotificationRequest` | `InteractionRequest<Notification> { get; private set; }` | Interaction request for displaying notifications. |
| `ConfirmationRequest` | `new InteractionRequest<Confirmation> { get; private set; }` | Interaction request for displaying confirmations. Hides base member. |
| `ContextNavigationRegion` | `object { get; set; }` | Gets or sets the content of the `NavigationRegion` on the concrete `NavigationView`. Raises `OnPropertyChanged` on set. |
| `HeaderInfo` | `string { get; }` | Returns the constant string `"NavigationRegion"`. |
| `IsBusy` | `new bool { get; set; }` | Throws `NotImplementedException` on both getter and setter. Hides base member. |
| `IsDirty` | `new bool { get; }` | Throws `NotImplementedException` on getter. Hides base member. |
| `IsNavigationIncluded` | `new bool { get; set; }` | Auto-property hiding base member. |
### Events
| Event | Signature | Description |
|-------|-----------|-------------|
| `PropertyChanged` | `new event PropertyChangedEventHandler` | Hides the base class event. Invoked via `OnPropertyChanged`. |
### Methods
| Method | Signature | Description |
|--------|-----------|-------------|
| `Initialize` | `override void Initialize()` | Empty override. No initialization logic. |
| `Initialize` | `override void Initialize(object parameter)` | Casts `parameter` to `IBaseViewModel` and assigns to private `Parent` field. |
| `OnRaiseNotification` | `void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)` | Private event handler. Converts `NotificationContentEventArgs` to `NotificationContentEventArgsWithoutTitle` and raises the `NotificationRequest`. |
---
## 3. Invariants
- `NavigationView` is assigned in the constructor and is expected to be non-null throughout the instance lifetime.
- The `DataContext` of `NavigationView` is always set to `this` (the ViewModel itself).
- `NotificationRequest` and `ConfirmationRequest` are initialized in the constructor and never reassigned.
- The `RaiseNotification` event subscription is established at construction time and remains active for the instance lifetime.
- `ContextNavigationRegion` property getter assumes `NavigationView` can be cast to the concrete `NavigationView` type and that `NavigationRegion` is non-null.
---
## 4. Dependencies
### This module depends on:
- `DTS.Common.Base``BaseViewModel<T>`, `IBaseViewModel`
- `DTS.Common.Events``RaiseNotification` (event), `NotificationContentEventArgs`
- `DTS.Common.Interactivity``InteractionRequest<T>`, `Notification`, `Confirmation`
- `DTS.Common.Interface``INavigationViewModel`, `INavigationView`
- `Prism.Events``IEventAggregator`
- `Prism.Regions``IRegionManager`
- `Unity``IUnityContainer`
### Consumers:
- Not determinable from this source file alone. The class is public and designed for use by other modules in the DTS.Viewer application.
---
## 5. Gotchas
1. **Member hiding with `new` keyword**: Multiple members (`ConfirmationRequest`, `IsBusy`, `IsDirty`, `IsNavigationIncluded`, `PropertyChanged`) use `new` to hide base class members. This can cause confusion when casting to base types or interfaces, as the hidden members will not be invoked.
2. **NotImplementedException on `IsBusy` and `IsDirty`**: Both properties throw `NotImplementedException` on access. Calling code must not attempt to read or write these properties.
3. **Concrete type cast in `ContextNavigationRegion`**: The property casts `INavigationView NavigationView` to the concrete `NavigationView` type to access `NavigationRegion.Content`. This breaks the abstraction provided by the interface and creates tight coupling to the concrete view implementation.
4. **Unused private fields**: `Parent`, `EventAggregator`, and `UnityContainer` are stored as private fields but `Parent` is only assigned (never read), and `EventAggregator`/`UnityContainer` are only used for subscription in the constructor. This may indicate incomplete implementation or dead code.
5. **ReSharper suppression directives**: The file contains multiple `// ReSharper disable` comments (`CheckNamespace`, `NotAccessedField.Local`, `UnusedAutoPropertyAccessor.Local`, `AutoPropertyCanBeMadeGetOnly.Local`), suggesting known code quality issues that have been suppressed rather than addressed.

View File

@@ -0,0 +1,78 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/TestModificationModule.cs
generated_at: "2026-04-16T11:04:46.076317+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "3f67001eaa6ddf3a"
---
# Documentation: TestModificationModule
## 1. Purpose
This module serves as the entry point for the "TestModification" feature within the DTS Viewer application. It implements the `IModule` interface from the Prism framework to handle dependency injection registration for the feature's View and ViewModel. Additionally, it defines assembly-level attributes to provide metadata (name, icon, region, and group) used by the main application shell to identify and display the module to the end-user.
## 2. Public Interface
### Class: `TestModificationModule`
The main module class responsible for registering application components.
* **Constructor**: `TestModificationModule(IUnityContainer unityContainer)`
* Accepts an `IUnityContainer` instance via dependency injection and stores it in a private readonly field.
* **Method**: `void RegisterTypes(IContainerRegistry containerRegistry)`
* Implements `IModule.RegisterTypes`. Invokes the private `Initialize()` method to register types with the Unity container.
* **Method**: `void OnInitialized(IContainerProvider containerProvider)`
* Implements `IModule.OnInitialized`. Currently contains no implementation logic.
### Class: `TestModificationModuleNameAttribute`
An assembly-level attribute providing the module's name metadata.
* **Constructor**: `TestModificationModuleNameAttribute()` / `TestModificationModuleNameAttribute(string s)`
* Initializes the `AssemblyName` property using the `AssemblyNames.TestModification` enum value.
* **Property**: `override string AssemblyName`
* Returns the string representation of `AssemblyNames.TestModification`.
* **Method**: `override Type GetAttributeType()`
* Returns `typeof(TextAttribute)`.
* **Method**: `override string GetAssemblyName()`
* Returns the `AssemblyName` property value.
### Class: `TestModificationModuleImageAttribute`
An assembly-level attribute providing image and grouping metadata for the module.
* **Constructor**: `TestModificationModuleImageAttribute()` / `TestModificationModuleImageAttribute(string s)`
* Initializes the assembly image by calling `AssemblyInfo.GetImage`.
* **Property**: `override BitmapImage AssemblyImage`
* Retrieves and caches a `BitmapImage` associated with `AssemblyNames.TestModification`.
* **Property**: `override string AssemblyName`
* Returns the string representation of `AssemblyNames.TestModification`.
* **Property**: `override string AssemblyGroup`
* Returns `eAssemblyGroups.Viewer.ToString()`.
* **Property**: `override eAssemblyRegion AssemblyRegion`
* Returns `eAssemblyRegion.TestModificationRegion`.
* **Methods**: `GetAssemblyImage()`, `GetAssemblyName()`, `GetAssemblyGroup()`, `GetAssemblyRegion()`
* Accessors returning the values of their respective properties defined above.
## 3. Invariants
* **Module Name**: The module is identified by the string "TestModification" via the `[Module]` attribute.
* **Assembly Region**: The module is strictly associated with `eAssemblyRegion.TestModificationRegion`.
* **Assembly Group**: The module belongs to the `eAssemblyGroups.Viewer` group.
* **Attribute Usage**: Both custom attributes are decorated with `[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]`, ensuring only one instance of each exists per assembly.
* **Registration**: The `ITestModificationView` interface is always mapped to the `TestModificationView` concrete type, and `ITestModificationViewModel` is mapped to `TestModificationViewModel`.
## 4. Dependencies
### Internal Dependencies
* **DTS.Common**: Used for `TextAttribute`, `ImageAttribute`, `AssemblyNames`, `AssemblyInfo`, `eAssemblyGroups`, and `eAssemblyRegion`.
* **DTS.Common.Interface**: Used for `ITestModificationView` and `ITestModificationViewModel` interfaces.
* **Concrete Types**: References `TestModificationView` and `TestModificationViewModel` (source files not provided, assumed to exist within the namespace).
### External Dependencies
* **Prism.Ioc**: Provides `IContainerProvider` and `IContainerRegistry`.
* **Prism.Modularity**: Provides `IModule` and `ModuleAttribute`.
* **Unity**: Provides `IUnityContainer` for dependency injection.
* **System.Windows.Media.Imaging**: Provides `BitmapImage` for image handling.
## 5. Gotchas
* **Comment/Code Mismatch**: The comment in `Initialize()` states: "Register View & View-Model ... as a singleton." However, the code uses `_unityContainer.RegisterType<...>()`. In Unity, `RegisterType` registers a transient mapping (new instance per resolve) by default, not a singleton. If a singleton is intended, `RegisterSingleton` or `RegisterInstance` should be used.
* **Mixed Container Usage**: The module receives an `IContainerProvider` in `OnInitialized` and an `IContainerRegistry` in `RegisterTypes` (standard Prism), but the constructor specifically requests the concrete `IUnityContainer`. The `Initialize` method uses this concrete `_unityContainer` reference to register types, bypassing the abstraction provided by `IContainerRegistry`. This ties the module specifically to the Unity container, reducing portability to other DI containers supported by Prism.
* **Unused Parameters**: The constructors for `TestModificationModuleNameAttribute` and `TestModificationModuleImageAttribute` accept a `string s` parameter that is effectively ignored (the logic inside relies on `AssemblyNames.TestModification` instead of the passed string).

View File

@@ -0,0 +1,262 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Model/Enums.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Model/TestModificationModel.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Model/TestModelManipulation.cs
generated_at: "2026-04-16T11:09:33.877186+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "1e3214665d63bf12"
---
# Test Modification Module Documentation
## 1. Purpose
This module provides functionality for modifying test data within the DTS Viewer application. It manages the state of user-initiated modifications to channel parameters (sensitivity, EU multiplier/offset, T0 timing, line fit, software filters, data flags, and descriptions) and handles the persistence of these changes to both `.dts` metadata files and binary `.chn` channel files. The module supports backup/restore operations to allow reverting modifications and maintains change tracking to indicate which properties have been modified from their original values.
---
## 2. Public Interface
### Enums.cs
#### `Keys` Enum
```csharp
public enum Keys
{
ApplyShiftT0ModsTestOnly // System Setting for whether to restrict "Shift T0" test modifications to "Test" only.
}
```
- Defines a configuration key for controlling T0 modification behavior.
---
### TestModificationModel.cs
#### `TestModificationModel` Class
Implements `ITestModificationModel`. A model class that tracks modification state for a selected test channel.
**Calibration Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `CalDate` | `string` | Returns calibration date as short date string, or empty if `Cal` is null. |
| `ModifyDate` | `string` | Returns modify date/time string, or empty if `Cal` is null. |
| `CalSensitivity` | `double` | Gets/sets sensitivity from first calibration record. Returns `double.NaN` if unavailable. |
| `ProportionalToExcitation` | `bool` | Returns whether calibration is proportional to excitation. |
| `ShowSensorCal` | `bool` | Returns true if `Cal` and `Sensor` are non-null and calibration is not non-linear. |
| `NonLinear` | `bool` | Returns whether calibration is non-linear. |
| `Cal` | `ISensorCalDbRecord` | The latest calibration record for the channel. |
| `Sensor` | `ISensorDbRecord` | The sensor corresponding to the channel. |
**Channel Selection & Modification Tracking:**
| Property | Type | Description |
|----------|------|-------------|
| `SelectedChannel` | `ITestChannel` | The currently selected test channel. |
| `Description` | `string` | Channel description string. |
| `IsModifiedDescription` | `bool` | True if `Description` differs from `SelectedChannel.ChannelDescriptionString`. |
| `EuMultiplier` | `double` | EU multiplier value. |
| `IsModifiedEuMultiplier` | `bool` | True if `EuMultiplier` differs from `SelectedChannel.Multiplier`. |
| `EuOffset` | `double` | EU offset value. |
| `IsModifiedEuOffset` | `bool` | True if `EuOffset` differs from `SelectedChannel.UserOffsetEu`. |
| `T0` | `double` | T0 timing offset (in ms). |
| `IsModifiedT0` | `bool` | True if `T0` is not 0. |
| `T1` | `double` | Line fit start point (in ms). |
| `T2` | `double` | Line fit end point (in ms). |
| `IsModifiedLineFit` | `bool` | True if `T1` or `T2` is not 0. |
| `Sensitivity` | `double` | Sensitivity value. |
| `IsModifiedSensitivity` | `bool` | True if `Sensitivity` differs from `SelectedChannel.Sensitivity`. |
| `SelectedFilter` | `IFilterClass` | Selected software filter (defaults to `FilterClassType.Unfiltered`). |
| `IsModifiedFilter` | `bool` | True if `SelectedFilter` differs from channel's software filter. |
| `SelectedDataFlag` | `DataFlag` | Selected data flag. |
| `IsModifiedDataFlag` | `bool` | True if `SelectedDataFlag` differs from channel's data flag. |
| `IsModified` | `bool` | Aggregate flag indicating any modification exists and `SelectedChannel` is not null. |
**Control Enable/Disable Properties:**
| Property | Type | Default |
|----------|------|---------|
| `EnableSensitivityControl` | `bool` | `true` |
| `EnableLineFitControl` | `bool` | `true` |
| `EnableEUOffsetControl` | `bool` | `true` |
| `EnableEUMultiplierControl` | `bool` | `true` |
| `EnableFilterControl` | `bool` | `true` |
| `EnableDescriptionControl` | `bool` | `true` |
| `IsDataFlagEnabled` | `bool` | `true` |
| `IsT0Enabled` | `bool` | `true` |
**T0 Mode Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `T0Mode` | `T0Mode` | Gets/sets T0 mode (`Test` or `DAS`). When `IsT0ModeTestOnly` is true, setter forces value to `T0Mode.Test`. |
| `IsT0ModeTestOnly` | `bool` | When true, restricts T0 mode to `Test` only. |
**Other Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `Parent` | `ITestModificationViewModel` | Reference to parent view model. |
| `IsSaved` | `bool` | Property exists but has no implementation visible. |
**Methods:**
```csharp
public bool ValidateT0()
```
- Validates that T0 falls within the dataset's time range (between start and end times).
- Returns `true` if `SelectedChannel` or `SelectedChannel.ParentModule` is null.
- Calculates valid range from `StartRecordSampleNumber`, `TriggerSampleNumbers[0]`, `NumberOfSamples`, and `SampleRateHz`.
```csharp
public void OnPropertyChanged(string propertyName)
```
- Raises `PropertyChanged` event.
- Updates `IsModified` aggregate flag when non-IsModified properties change.
- Calls `Parent?.PublishChanges()`.
**Commands:**
```csharp
public DelegateCommand UpdateDatabaseCommand
```
- Executes `UpdateDatabaseMethod()` which delegates to `Parent.UpdateDatabaseMethod()`.
---
### TestModelManipulation.cs
#### `TestModelManipulation` Class
Static utility class for file-based test modification operations.
**Constants:**
| Constant | Value | Description |
|----------|-------|-------------|
| `UNUSED_START_TIME` | `0` | Placeholder for test serialization. |
| `UNUSED_DATA_COLLECTION_LENGTH` | `0` | Placeholder for test serialization. |
| `BackupHeaderExtension` | `".header.bak"` | Extension for header-only backups. |
| `BackupFileExtension` | `".bak"` | Extension for full file backups. |
**Public Methods:**
```csharp
public static void UndoAllModification(ITestModificationModel model)
```
- Reverts all modifications by restoring `.dts` and all `.chn` files from backups.
- Publishes `ChannelsModificationNotification`, `RefreshTestRequestEvent`, and `TestModificationEvent`.
```csharp
public static bool BackupExists(ITestModificationModel model)
```
- Returns true if either `.dts.bak` or `.chn.bak` files exist for the selected channel.
```csharp
public static bool SaveModification(ITestModificationModel model, bool useISOCodeFilterMapping, bool bUseZeroForUnfiltered)
```
- Persists all modifications to disk.
- Handles T0 changes (applying to test or DAS based on `T0Mode`).
- Handles filter changes with optional ISO code mapping.
- Handles sensitivity, EU multiplier/offset, description, data flag, and line fit changes.
- Publishes `TestModificationEvent` on completion.
```csharp
public static bool SaveModificationDataFlag(ITestModificationModel model)
```
- Saves only data flag modifications.
- Publishes `ChannelsModificationNotification` and repopulates model from channel.
```csharp
public static void ApplyLineFit(ITestModificationModel model, Test.Module.Channel channel)
```
- Applies linear interpolation between sample indices derived from `T1` and `T2`.
- Backs up channel file (full backup, not header-only).
- Modifies ADC data in place using straight-line fit between two points.
```csharp
public static void PreviewLineFit(ITestModificationModel model)
```
- Publishes `ChannelsModificationLineFitNotification` with calculated start/end indices for UI preview without disk modification.
```csharp
public static void UndoModification(ITestModificationModel model)
```
- Reverts in-memory changes by repopulating from channel.
- Publishes `ChannelsModificationNotification`.
```csharp
public static void PopulateFromChannel(ITestModificationModel model)
```
- Initializes model properties from `SelectedChannel` values.
- Resets `T0`, `T1`, `T2` to 0.
---
## 3. Invariants
1. **Calibration Record Access**: `CalSensitivity` getter assumes `Cal.Records.Records[0]` exists if the collection is non-null and non-empty. No bounds checking beyond length > 0.
2. **Modification Flag Consistency**: `IsModified` is always `false` when `SelectedChannel` is null, regardless of other modification flags.
3. **T0Mode Restriction**: When `IsT0ModeTestOnly` is `true`, the `T0Mode` setter always forces the value to `T0Mode.Test`, ignoring the provided value.
4. **Backup File Semantics**: Backup files (`.bak`) represent the **original** unmodified files. If a backup exists, it is never overwritten by subsequent backup operations.
5. **Line Fit Index Ordering**: `ApplyLineFit` automatically swaps start/end indices if `startIndex > endIndex`.
6. **T0 Validation Range**: `ValidateT0()` calculates time range assuming `TriggerSampleNumbers[0]` exists (no bounds check on the list).
7. **Channel Matching**: `SaveModification` matches channels by both `ChannelId` AND `BinaryFileName` suffix for most operations (except T0 modifications which apply more broadly).
---
## 4. Dependencies
### Imports (This module depends on):
**From TestModificationModel.cs:**
- `DTS.Common` - Common utilities
- `DTS.Common.Classes.Sensors` - Sensor classes
- `DTS.Common.Enums.Sensors` - Sensor enums
- `DTS.Common.Interface` - Common interfaces
- `DTS.Common.Interface.Sensors` - Sensor interfaces
- `DTS.Common.Interface.Sensors.SoftwareFilters` - Filter interfaces
- `DTS.SensorDB` - Sensor database interfaces (`ISensorCalDbRecord`, `ISensorDbRecord`)
- `Prism.Commands` - `DelegateCommand`
**From TestModelManipulation.cs:**
- `DTS.Common` - Common utilities
- `DTS.Common.Classes.Sensors` - Sensor classes
- `DTS.Common.Events` - Event types (`TestModificationEvent`, `TestModificationArgs`, `ChannelsModificationNotification`, `ChannelsModificationLineFitNotification`, `LineFitArgs`, `RefreshTestRequestEvent`)
- `DTS.Common.Interface` - `ITestChannel`
- `DTS.Common.Settings` - `SettingsDB`
- `DTS.Common.Utilities.Logging` - `APILogger`
- `DTS.Serialization` - Serialization utilities (`Serialization.SliceRaw.File`)
- `Prism.Ioc` - `ContainerLocator`
- `Prism.Events` - `IEventAggregator`
### External Type References (Interfaces expected from elsewhere):
- `ITestModificationModel` - Interface implemented by `TestModificationModel`
- `ITestModificationViewModel` - Parent view model interface
- `ITestChannel` - Test channel interface
- `ISensorCalDbRecord` - Calibration database record
- `ISensorDbRecord` - Sensor database record
- `IFilterClass` / `FilterClass` - Software filter abstraction
- `T0Mode` - Enum for T0 modification scope
- `DataFlag` - Enum for data flags
- `Test.Module.Channel` / `Test.Module.AnalogInputChannel` - Channel types from serialization
- `Test` / `TestSetup` - Test structure types
---
## 5. Gotchas
1. **Namespace Mismatch**: `TestModificationModel.cs` is declared in namespace `DTS.Viewer.ChartOptions.Model` despite residing in `DTS.Viewer.TestModification/Model/`. This may cause confusion when locating the class.
2. **IsSaved Property**: The `IsSaved` property has a getter but no visible setter or backing field implementation. Its behavior is unclear from source alone.
3. **T0 Mode DAS Logic**: In `SaveModification`, when `T0Mode == T0Mode.DAS`, T0 changes are applied to modules that **do not** contain the selected channel but share the same `BaseSerialNumber` as the module that does. This could affect more channels than expected.
4. **Line Fit Data Type**: `ApplyLineFit` casts ADC data to `short` after floating-point interpolation, which could cause precision loss or overflow for extreme values.
5. **Thread.Sleep in File Writing**: `WriteDTSFileChanges` includes `System.Threading.Thread.Sleep(10)` after writing the DTS file. The reason for this delay is not documented in source.
6. **Backup Strategy Selection**: `BackupChannelIfNeeded` uses header-only backup for sensitivity/T0/filter changes (when `useISOCodeFilterMapping` is true), but full backup for line fit. This is a performance optimization but means different modification types have different restore behaviors.
7. **FilterClassType Default**: `SelectedFilter` defaults to `FilterClassType.Unfiltered`, but the source does not show the definition of `FilterClassType` enum.
8. **PropertyChanged Event Naming**: `RebindCalProperties` raises events with string property names rather than using `nameof()` operator, which could lead to runtime errors if property names change.

View File

@@ -0,0 +1,47 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T11:08:52.753562+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "159c8c375f9a8da3"
---
# Properties
## Documentation: DTS.Viewer.TestModification Assembly Configuration
### 1. Purpose
This file provides assembly-level metadata and configuration for the `DTS.Viewer.TestModification` module. It exists to define the identity, versioning, and COM visibility settings for the compiled output (DLL or EXE) using standard .NET attributes. Its role is strictly configuration; it contains no executable logic or type definitions.
### 2. Public Interface
This file does not expose classes or methods. It configures the following assembly-level attributes:
* **`AssemblyTitle`**: Set to `"DTS.Viewer.TestModification"`.
* **`AssemblyDescription`**: Set to an empty string.
* **`AssemblyConfiguration`**: Set to an empty string.
* **`AssemblyCompany`**: Set to an empty string.
* **`AssemblyProduct`**: Set to `"DTS.Viewer.TestModification"`.
* **`AssemblyCopyright`**: Set to `"Copyright © 2017"`.
* **`AssemblyTrademark`**: Set to an empty string.
* **`AssemblyCulture`**: Set to an empty string (indicates the assembly is culture-neutral).
* **`ComVisible`**: Set to `false`. This prevents types within this assembly from being visible to COM components by default.
* **`Guid`**: Set to `"5ee7c61f-e9fe-479b-be1f-78a142341c3b"`. This acts as a unique identifier for the assembly if exposed to COM.
* **`AssemblyVersion`**: Set to `"1.0.0.0"`.
* **`AssemblyFileVersion`**: Set to `"1.0.0.0"`.
### 3. Invariants
* **Versioning:** The assembly version and file version are explicitly pinned to `1.0.0.0`. They will not auto-increment with builds unless this file is modified or the project is configured to override these attributes elsewhere (e.g., in a CI/CD pipeline).
* **COM Visibility:** All types in this assembly are hidden from COM components unless a specific type overrides this by applying `[ComVisible(true)]` at the class level.
### 4. Dependencies
* **Internal Dependencies:**
* `System.Reflection`
* `System.Runtime.CompilerServices`
* `System.Runtime.InteropServices`
* **External Consumers:** The compiled assembly produced by the `DTS.Viewer.TestModification` project depends on this configuration for its identity. The build system consumes this file to embed the manifest resource.
### 5. Gotchas
* **Empty Metadata:** Several fields (`AssemblyDescription`, `AssemblyCompany`, `AssemblyConfiguration`) are initialized but left empty. This may result in incomplete metadata in the compiled binary properties.
* **Legacy Project Format:** The existence of this file suggests a traditional .NET Framework project structure (non-SDK style). Modern .NET Core/5+ projects typically define these properties in the `.csproj` file.
* **Hardcoded Version:** The version numbers are hardcoded. If the codebase evolves, these versions must be manually updated here to reflect new releases.

View File

@@ -0,0 +1,83 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Resources/TranslateExtension.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/Resources/StringResources.Designer.cs
generated_at: "2026-04-16T11:08:29.234915+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "46010437bced3eec"
---
# Documentation: DTS.Viewer.TestModification.Resources
## 1. Purpose
This module provides localization support for the `DTS.Viewer.TestModification` namespace. It consists of a strongly-typed resource wrapper class, `StringResources`, which provides compile-time access to localized strings (likely sourced from a `.resx` file), and a XAML markup extension, `TranslateExtension`, that allows WPF UI elements to bind to these localized strings declaratively.
## 2. Public Interface
### Class: `TranslateExtension`
**Namespace:** `DTS.Viewer.TestModification`
**Inheritance:** `System.Windows.Markup.MarkupExtension`
This class allows XAML bindings to retrieve localized strings using a resource key.
* **Constructor**
* `public TranslateExtension(string key)`: Initializes the extension with the specific resource key to look up.
* **Method**
* `public override object ProvideValue(IServiceProvider serviceProvider)`: Returns the localized string associated with the `_key`. If the key is null, empty, or not found in the resource manager, it returns an error string constant.
### Class: `StringResources`
**Namespace:** `DTS.Viewer.TestModification.Resources`
**Accessibility:** `internal`
A strongly-typed resource class auto-generated by Visual Studio. It exposes localized strings as static properties.
* **Properties**
* `internal static global::System.Resources.ResourceManager ResourceManager`: Returns the cached `ResourceManager` instance responsible for retrieving resources.
* `internal static global::System.Globalization.CultureInfo Culture`: Gets or sets the current `CultureInfo` used for resource lookups.
* **Resource String Properties (Static)**
* `string CalDate`: "Cal date"
* `string DataFlag`: "Data Flag:"
* `string Description`: "Description:"
* `string EUMultiplier`: "EU Multiplier:"
* `string EUOffset`: "EU Offset:"
* `string FailedToModifySensitivity`: "Failed to modify sensitivity: "
* `string Filter`: "Filter:"
* `string LineFit`: "Line Fit:"
* `string ModifyDate`: "Modify date"
* `string NonLinear`: "Non-linear"
* `string PleaseLockHeader`: "To enable, please lock a single channel."
* `string Preview`: "Preview"
* `string ProportionalToExcitation`: "Proportional to excitation"
* `string Sensitivity`: "Sensitivity:"
* `string SensorCalibration`: "Sensor calibration (most recent in db)"
* `string ShiftT0ms`: "Shift T₀ (ms):"
* `string T0MustBeInDataset`: "Modification can not be made, T0 must be in the dataset."
* `string T1ms`: "T₁ (ms):"
* `string T2ms`: "T₂ (ms):"
* `string Undo`: "Cancel"
* `string UndoAll`: "Restore All"
* `string UndoAllPrompt`: "This will revert your saved test modifications to the backup on file. Continue?"
* `string UndoPrompt`: "This will undo any change(s) to this channel made before saving. Continue?"
* `string UpdateDatabase`: "Update database"
* `string WriteFiles`: "Write"
* `string WriteFilesPrompt`: "Are you sure you want to write these changes to disk?"
## 3. Invariants
* **Non-Null Return:** `TranslateExtension.ProvideValue` will never return `null`. It guarantees a string return, either the localized value or a specific error identifier.
* **Error Identifier:** If a resource key is not found, the return value must contain the constant `#stringnotfound#`. If the key is null or empty, it returns exactly `#stringnotfound#`. If the key is valid but missing from resources, it returns `#stringnotfound#` followed by a space and the missing key.
* **Auto-generation:** `StringResources` is marked with `GeneratedCodeAttribute`. Its members are strictly derived from the underlying resource source (e.g., `.resx`). Manual modifications to this file will be lost upon regeneration.
## 4. Dependencies
* **Internal Dependencies:**
* `TranslateExtension` depends on `StringResources` to perform the actual string lookup via `StringResources.ResourceManager`.
* **External Dependencies:**
* `System.Windows.Markup`: Required for `MarkupExtension` and `MarkupExtensionReturnTypeAttribute` (WPF specific).
* `System.Resources`: Required for `ResourceManager`.
* `System.Globalization`: Required for `CultureInfo`.
## 5. Gotchas
* **Auto-Generated File:** `StringResources.Designer.cs` is auto-generated. Developers must edit the corresponding `.resx` file (not present in the provided source) to add or modify strings; editing this `.cs` file directly is futile as changes will be overwritten.
* **Internal Visibility:** The `StringResources` class is `internal`. It cannot be accessed from outside the `DTS.Viewer.TestModification` assembly.
* **Silent Failures in UI:** `TranslateExtension` does not throw exceptions for missing keys. Instead, it returns strings like `#stringnotfound# MissingKey`. This behavior aids in debugging missing translations visually in the UI but requires the developer to inspect the string content rather than catching exceptions.
* **Static Culture:** The `StringResources.Culture` property is static. Changing it will affect all subsequent resource lookups within that assembly context, which implies the application is responsible for managing the UI culture lifecycle globally.

View File

@@ -0,0 +1,56 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/View/TestModificationView.xaml.cs
generated_at: "2026-04-16T11:09:12.708524+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "3165a969f0d942bf"
---
# Documentation: TestModificationView
## 1. Purpose
`TestModificationView` is a WPF user control that provides the interaction logic for a view related to test modification functionality. It implements the `ITestModificationView` interface and exposes available filter classes (CFC - Channel Filter Classes) for use in the UI, specifically retrieving filter options from `AnalogSettingDefaults`. The module appears to be part of a larger sensor data viewing and modification system within the DTS Viewer application.
## 2. Public Interface
### `TestModificationView()` (Constructor)
**Signature:** `public TestModificationView()`
Initializes a new instance of the view by calling `InitializeComponent()`, which loads the XAML-defined UI components.
---
### `AvailableCFC` (Property)
**Signature:** `public List<IFilterClass> AvailableCFC { get; }`
**Behavior:** Returns a list of available filter classes by instantiating a new `AnalogSettingDefaults` object and accessing its `FilterOptions` property. This property is read-only (getter only). The comment references "FB 13120" indicating this was implemented for a specific feature request or bug fix.
## 3. Invariants
- The `AvailableCFC` property will never return `null` (assuming `AnalogSettingDefaults.FilterOptions` never returns `null`).
- Each call to `AvailableCFC` creates a new `AnalogSettingDefaults` instance; the property does not cache or reuse a single instance.
- The view must be initialized via `InitializeComponent()` before any UI element access.
## 4. Dependencies
### This module depends on:
- `DTS.Common.Interface` - Provides `ITestModificationView` interface that this class implements
- `DTS.Common.Interface.Sensors.SoftwareFilters` - Provides `IFilterClass` interface used in the `AvailableCFC` property return type
- `DTS.SensorDB` - Provides `AnalogSettingDefaults` class used to retrieve filter options
- `System.Windows.Controls` - WPF base classes (UserControl, inferred from partial class pattern)
- `System.Collections.Generic` - Provides `List<T>` collection type
### What depends on this module:
- Cannot be determined from source alone. Consumers would be modules that reference `ITestModificationView` or directly instantiate `TestModificationView`.
## 5. Gotchas
1. **Unused import:** `System.Text.RegularExpressions` is imported but never used in this file. This may indicate leftover code from refactoring.
2. **Namespace suppression:** The file includes `// ReSharper disable CheckNamespace`, suggesting the namespace `DTS.Viewer.TestModification` may not match the project's folder structure conventions, or ReSharper is flagging a namespace mismatch.
3. **Property allocation pattern:** The `AvailableCFC` property instantiates a new `AnalogSettingDefaults` object on every access. If called frequently (e.g., in a binding or loop), this could create unnecessary object allocations. Consider whether caching would be appropriate.
4. **FB 13120 reference:** The comment references a tracking identifier (likely FogBugz or similar issue tracker). The context and resolution of this issue are not documented in code.

View File

@@ -0,0 +1,133 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestModification/ViewModel/TestModificationViewModel.cs
generated_at: "2026-04-16T11:08:10.828283+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "297454e79e1ccbbd"
---
# Documentation: TestModificationViewModel
## 1. Purpose
`TestModificationViewModel` is a Prism-based ViewModel responsible for managing test data modifications within the DTS Viewer application. It provides functionality to modify channel properties such as T0 (time zero), sensitivity, line fit, EU multipliers/offsets, filters, and data flags. The module interfaces with the sensor database to retrieve and update calibration records, and coordinates with the broader application via event aggregation for channel selection, T0 shifting, and modification state synchronization.
---
## 2. Public Interface
### Constructor
```csharp
public TestModificationViewModel(
ITestModificationView view,
IRegionManager regionManager,
IEventAggregator eventAggregator,
IUnityContainer unityContainer)
```
Initializes the ViewModel, sets up the View's DataContext, creates interaction requests, and subscribes to `RaiseNotification`, `GraphSelectedChannelsNotification`, `ShiftT0Event`, and `SetUseZeroForUnfilteredEvent` events.
---
### Public Methods
| Method | Signature | Description |
|--------|-----------|-------------|
| `Initialize` | `void Initialize()` | Override; no-op implementation. |
| `Initialize` | `void Initialize(object parameter)` | Override; sets `Parent` property from parameter cast to `IBaseViewModel`. |
| `UpdateDatabaseMethod` | `void UpdateDatabaseMethod()` | Updates calibration in the sensor database. Sets `CalibrationId` to -1, updates `ModifyDate` to current time, creates a new `SensorCalibration`, inserts via `DbOperations.SensorCalibrationsInsert`, and refreshes `Model.Cal` with latest calibration. Publishes `PageErrorEvent` on failure. |
| `PublishChanges` | `void PublishChanges()` | If `Model.IsModifiedDataFlag` is true, saves data flag modification immediately via `TestModelManipulation.SaveModificationDataFlag`. Publishes `TestModificationChangedEvent` with the Model. |
---
### Public Properties
| Property | Type | Description |
|----------|------|-------------|
| `View` | `ITestModificationView` | Gets/sets the associated View. |
| `Parent` | `IBaseViewModel` | Gets/sets the parent ViewModel. |
| `NotificationRequest` | `InteractionRequest<Notification>` | Interaction request for displaying notifications. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | Interaction request for displaying confirmations. |
| `PreviewCommand` | `DelegateCommand` | Executes `PreviewMethod()` - calls `TestModelManipulation.PreviewLineFit(Model)`. |
| `WriteCommand` | `DelegateCommand` | Executes `WriteMethod()` - validates T0, prompts user, calls `TestModelManipulation.SaveModification`. |
| `UndoCommand` | `DelegateCommand` | Executes `UndoMethod()` - prompts user, calls `TestModelManipulation.UndoModification`. |
| `UndoAllCommand` | `DelegateCommand` | Executes `UndoAllMethod()` - prompts user, calls `TestModelManipulation.UndoAllModification`. |
| `UseISOCodeFilterMapping` | `bool` | Controls whether ISOCode field filter matches channel's SoftwareFilter. Default: `false`. |
| `Model` | `TestModificationModel` | The model containing test modification state. Setter updates `Parent` reference. |
| `UseZeroForUnfiltered` | `bool` | Gets/sets whether to use zero for unfiltered values. |
| `IsFilterEnabled` | `bool` | Gets/sets filter enabled state. Raises `OnPropertyChanged`. |
| `TestModificationVisability` | `bool` | Controls visibility of test modification UI. Raises `OnPropertyChanged`. |
| `HeaderInfo` | `string` | Returns `"TestSummaryRegion"`. |
| `IsBusy` | `bool` | Gets/sets busy state. Raises `OnPropertyChanged`. |
| `IsDirty` | `bool` | Gets/sets dirty state. |
| `IsNavigationIncluded` | `bool` | Gets/sets navigation inclusion state. |
| `IsBackedUp` | `bool` | Gets (private sets) whether backup exists. Raises `OnPropertyChanged`. |
---
### Events
| Event | Type | Description |
|-------|------|-------------|
| `PropertyChanged` | `PropertyChangedEventHandler` | Raised when a property value changes. |
---
## 3. Invariants
1. **Single-Channel Selection**: `TestModificationVisability` is `true` only when exactly one channel is selected (`channels.Count == 1 && channels.Count(x => x.IsSelected) == 1`).
2. **T0 Validation**: T0 cannot be shifted beyond the bounds of the test dataset. `Model.ValidateT0()` must return `true` before write operations proceed.
3. **Calibration ID Reset**: When updating the database via `UpdateDatabaseMethod()`, `CalibrationId` is always set to `-1` before insertion.
4. **Analog Sensor Calibration Display**: Calibration records are only loaded/displayed for sensors where `SensorType == 0` (analog sensors).
5. **Calibration Sorting**: Calibrations are sorted ascending by `CalibrationDate`, then by `ModifyDate` as a tiebreaker. The "latest" calibration is the last element after sorting.
6. **Permission-Based Controls**: All edit controls (`EnableSensitivityControl`, `EnableLineFitControl`, `EnableDescriptionControl`, `EnableEUMultiplierControl`, `EnableEUOffsetControl`, `EnableFilterControl`, `IsT0Enabled`, `IsDataFlagEnabled`) are gated by `viewModel.DoesUserHaveEditPermission`.
---
## 4. Dependencies
### This Module Depends On:
- `DTS.Common.Base` - `BaseViewModel<T>`
- `DTS.Common.Events` - Event types (`PageErrorEvent`, `RaiseNotification`, `GraphSelectedChannelsNotification`, `ShiftT0Event`, `SetUseZeroForUnfilteredEvent`, `TestModificationChangedEvent`, `ShowT0CursorEvent`)
- `DTS.Common.Interactivity` - `InteractionRequest<T>`, `Notification`, `Confirmation`
- `DTS.Common.Interface` - `IBaseViewModel`, `ITestModificationViewModel`, `ITestModificationView`, `IViewerMainViewModel`
- `DTS.Common.Interface.Sensors` - `ISensorDbRecord`, `ISensorCalDbRecord`
- `DTS.Common.Settings` - `SettingsDB`, `Keys`
- `DTS.Common.Storage` - (content not visible, inferred from namespace)
- `DTS.Common.Utilities.Logging` - `APILogger`
- `DTS.SensorDB` - `DbOperations`, `SensorCalibration`
- `DTS.Viewer.ChartOptions.Model` - (content not visible)
- `DTS.Viewer.TestModification.Model` - `TestModificationModel`, `TestModelManipulation`
- `Prism.Commands` - `DelegateCommand`
- `Prism.Events` - `IEventAggregator`
- `Prism.Regions` - `IRegionManager`
- `Unity` - `IUnityContainer`
### What Depends On This Module:
- Not determinable from source alone. Inferred consumers would be the View (`TestModificationView`) and the main application shell via region navigation.
---
## 5. Gotchas
1. **Typo in Property Name**: `TestModificationVisability` is misspelled (should be "Visibility"). This may cause confusion when referencing the property.
2. **Malformed XML Comment**: The `GetLatestCalibration` method has a malformed XML comment with `<summary>` used as both opening and closing tag instead of `</summary>`.
3. **Silent Exception Swallowing**: `GetLatestCalibration` catches all exceptions and returns `null` without logging. The comment explicitly states: *"there's no access to APILogger here, so rather than adding a reference, just eat the error"*.
4. **Member Hiding with `new` Keyword**: Several members (`OnPropertyChanged`, `PropertyChanged`, `IsBusy`, `IsDirty`, `IsNavigationIncluded`) use the `new` keyword to hide base class members, which can lead to unexpected behavior when casting to base types.
5. **Yoda Condition Style**: The codebase uses Yoda conditions (`null == sensor` instead of `sensor == null`) consistently throughout.
6. **Hardcoded Calibration ID**: `cal.CalibrationId = -1` is used as a marker for new calibrations. The significance of `-1` is not documented in code.
7. **Static `IsPopulating` Property**: `IsPopulating` is a static property used to prevent `PublishChanges` from executing during model population, which could cause issues if multiple instances exist.
8. **Feature Request Reference**: A comment references an internal case URL: `http://manuscript.dts.local/f/cases/43735/` for the database update feature.

View File

@@ -0,0 +1,109 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestSummaryList/TestSummaryListModule.cs
generated_at: "2026-04-16T11:06:42.997864+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "b68514768022da67"
---
# Documentation: TestSummaryListModule.cs
## 1. Purpose
This module serves as a Prism-based module initializer for the Test Summary List feature within the DTS Viewer application. Its primary role is to register the view (`TestSummaryListView`) and view model (`TestSummaryViewListModel`) with the Unity dependency injection container, enabling the main application to discover and load this component. Additionally, it provides assembly-level metadata attributes that define the module's name, display image, region assignment, and group classification for use by the main shell's module management system.
---
## 2. Public Interface
### `TestSummaryListModule` (Class)
**Signature:** `public class TestSummaryListModule : IModule`
A Prism module that handles registration of the Test Summary List view and view model.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `TestSummaryListModule(IUnityContainer unityContainer)` | Accepts an injected `IUnityContainer` instance and stores it in `_unityContainer`. |
| `Initialize` | `public void Initialize()` | Registers `ITestSummaryListView``TestSummaryListView` and `ITestSummaryListViewModel``TestSummaryViewListModel` with Unity. |
| `OnInitialized` | `public void OnInitialized(IContainerProvider containerProvider)` | Empty implementation (no-op). |
| `RegisterTypes` | `public void RegisterTypes(IContainerRegistry containerRegistry)` | Calls `Initialize()` to perform type registrations. |
---
### `TestSummaryListModuleNameAttribute` (Class)
**Signature:** `public class TestSummaryListModuleNameAttribute : TextAttribute`
Assembly-level attribute providing the module's name metadata.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `TestSummaryListModuleNameAttribute()` | Default constructor; sets `AssemblyName` to `AssemblyNames.TestSummaryList.ToString()`. |
| Constructor | `TestSummaryListModuleNameAttribute(string s)` | Overload accepting a string parameter (unused). |
| `AssemblyName` | `public override string AssemblyName { get; }` | Returns `AssemblyNames.TestSummaryList.ToString()`. |
| `GetAttributeType` | `public override Type GetAttributeType()` | Returns `typeof(TextAttribute)`. |
| `GetAssemblyName` | `public override string GetAssemblyName()` | Returns the `AssemblyName` property value. |
---
### `TestSummaryListModuleImageAttribute` (Class)
**Signature:** `public class TestSummaryListModuleImageAttribute : ImageAttribute`
Assembly-level attribute providing the module's image, name, group, and region metadata for display in the main application shell.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `TestSummaryListModuleImageAttribute()` | Default constructor; initializes `_img` via `AssemblyInfo.GetImage()`. |
| Constructor | `TestSummaryListModuleImageAttribute(string s)` | Overload accepting a string parameter (unused). |
| `AssemblyImage` | `public override BitmapImage AssemblyImage { get; }` | Lazy-loads and returns image via `AssemblyInfo.GetImage(AssemblyNames.TestSummaryList.ToString())`. |
| `AssemblyName` | `public override string AssemblyName { get; }` | Returns `AssemblyNames.TestSummaryList.ToString()`. |
| `AssemblyGroup` | `public override string AssemblyGroup { get; }` | Returns `eAssemblyGroups.Viewer.ToString()`. |
| `AssemblyRegion` | `public override eAssemblyRegion AssemblyRegion { get; }` | Returns `eAssemblyRegion.TestSummaryRegion`. |
| `GetAssemblyImage` | `public override BitmapImage GetAssemblyImage()` | Returns `AssemblyImage`. |
| `GetAssemblyName` | `public override string GetAssemblyName()` | Returns `AssemblyName`. |
| `GetAssemblyGroup` | `public override string GetAssemblyGroup()` | Returns `AssemblyGroup`. |
| `GetAssemblyRegion` | `public override eAssemblyRegion GetAssemblyRegion()` | Returns `AssemblyRegion`. |
| `GetAttributeType` | `public override Type GetAttributeType()` | Returns `typeof(ImageAttribute)`. |
---
## 3. Invariants
- **Module Name Consistency:** The `Module` attribute's `ModuleName` property is hardcoded as `"TestSummaryList"` and must match the `AssemblyNames.TestSummaryList` enum value's string representation.
- **Single Instance per Assembly:** Both assembly attributes use `AllowMultiple = false`, ensuring only one name and one image attribute can be applied per assembly.
- **Region Assignment:** The module is always assigned to `eAssemblyRegion.TestSummaryRegion`.
- **Group Assignment:** The module is always assigned to `eAssemblyGroups.Viewer`.
- **Attribute Target:** Both attributes are restricted to `AttributeTargets.Assembly` only.
---
## 4. Dependencies
### This Module Depends On:
| Dependency | Usage |
|------------|-------|
| `Prism.Ioc` | `IContainerProvider` interface for `OnInitialized` |
| `Prism.Modularity` | `IModule` interface and `Module` attribute |
| `Unity` | `IUnityContainer` for DI registration |
| `System.Windows.Media.Imaging` | `BitmapImage` for module icon |
| `DTS.Common` | `AssemblyNames` enum, `eAssemblyGroups` enum, `eAssemblyRegion` enum, `AssemblyInfo` static class |
| `DTS.Common.Interface` | `TextAttribute`, `ImageAttribute` base classes |
| `DTS.Viewer.TestSummaryList.ViewModel` | `ITestSummaryListViewModel`, `TestSummaryViewListModel` |
| Local (same assembly) | `ITestSummaryListView`, `TestSummaryListView` |
### What Depends On This Module:
- The main DTS Viewer shell application (inferred from Prism modularity pattern and assembly-level metadata attributes used for module discovery)
---
## 5. Gotchas
1. **Misleading Singleton Comment:** The comment on line 35 states "Register View & View-Model with Unity dependency injection container as a singleton," but `RegisterType<TFrom, TTo>()` registers types as **transient** by default in Unity, not as singletons. To register as singletons, `RegisterType<TFrom, TTo>(new ContainerControlledLifetimeManager())` or `RegisterSingleton<TFrom, TTo>()` should be used. The actual behavior may not match the comment's intent.
2. **Unusual View Model Class Name:** The concrete view model class is named `TestSummaryViewListModel` (line 39), which appears to be a typo or unconventional naming—typically one would expect `TestSummaryViewModel`. This is the actual class name in the source, not a documentation error.
3. **Redundant `Initialize()` Method:** The `Initialize()` method is public and called from `RegisterTypes()`, but it could be inlined. Having it public allows external code to call it, which could cause duplicate registrations.
4. **Unused Constructor Parameters:** Both attribute constructors accept a `string s` parameter that is never used in the constructor body. This appears to be boilerplate code required by the .NET attribute system for XAML or reflection usage.
5. **Lazy Initialization Side Effect:** The `AssemblyImage` property getter has a side effect—it assigns to `_img` on every get. While the constructor also initializes `_img`, the property getter will re-fetch the image each time, potentially causing unnecessary work if called repeatedly.

View File

@@ -0,0 +1,89 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestSummaryList/Model/TestSummaryModel.cs
generated_at: "2026-04-16T11:17:27.563683+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "eacbbab8741bd493"
---
# Documentation: TestSummaryModel.cs
## 1. Purpose
`TestSummaryModel` is a model class within the `DTS.Viewer.TestSummaryList` module that orchestrates loading and merging test summary data from `.dts` files. It implements `IBaseModel` and serves as the data acquisition layer for the test summary list view, handling asynchronous file system operations, event publication for UI state management (busy indicators, app status), and intelligent merging of newly loaded tests with existing collections while preserving user selection state.
---
## 2. Public Interface
### Properties
| Signature | Description |
|-----------|-------------|
| `ITestSummaryListViewModel Parent { get; set; }` | Reference to the parent view model. Must be set before calling `GetTestSummary`. Used to access and modify `TestSummaryList`, `SelectedTestSummaryList`, and `IsBusy` state. |
| `IEventAggregator _eventAggregator { get; set; }` | Prism event aggregator for publishing events. Despite the underscore prefix (typically indicating private), this is a public property. Must be set before calling `GetTestSummary`. |
| `bool IsSaved { get; }` | Read-only property. Appears to be an unimplemented auto-property (always returns default `false`). |
### Methods
| Signature | Description |
|-----------|-------------|
| `void GetTestSummary(string path, string file, bool Include = false, bool selectAll = false)` | Loads test definitions from the specified path/file. Creates the directory if it doesn't exist. Merges results into `Parent.TestSummaryList`, replacing duplicates (matched by `Id`, `SetupName`, and `DataType`) while preserving selection state. Publishes `BusyIndicatorChangeNotification`, `AppStatusExEvent`, and `TestLoadedCountNotification` events. Executes work asynchronously via `Dispatcher.CurrentDispatcher.InvokeAsync` with `DispatcherPriority.Background`. |
| `void OnPropertyChanged(string propertyName)` | Raises the `PropertyChanged` event for the specified property name. |
### Events
| Event | Description |
|-------|-------------|
| `event PropertyChangedEventHandler PropertyChanged` | Standard `INotifyPropertyChanged` implementation. |
---
## 3. Invariants
- **Parent must be assigned** before calling `GetTestSummary`. The method accesses `Parent.IsBusy`, `Parent.TestSummaryList`, and `Parent.SelectedTestSummaryList` without null checks.
- **_eventAggregator must be assigned** before calling `GetTestSummary`. Events are published without null checks.
- **Duplicate detection key**: Tests are considered duplicates if they match on all three properties: `Id`, `SetupName`, and `DataType`.
- **Selection preservation**: When replacing a duplicate test, the `IsSelected` state is preserved from the replaced test.
- **Collection event handling**: When `Parent.TestSummaryList` is empty, the new list is assigned directly and `CollectionChanged` is wired to `Parent.TestSummaryList_CollectionChanged`. When non-empty, items are added/inserted individually.
- **Async execution**: `GetTestSummary` returns immediately; actual work is dispatched asynchronously. Callers cannot await completion.
---
## 4. Dependencies
### This module depends on:
- `DTS.Common.Base``IBaseModel` interface
- `DTS.Common.Classes.Viewer.TestMetadata``TestMetadataList` class
- `DTS.Common.Events``BusyIndicatorChangeNotification`, `AppStatusExEvent`, `AppStatusExArg`, `AppStatusArg`, `TestLoadedCountNotification`, `TestLoadedCountNotificationArg`
- `DTS.Common.Interface` — (specific interfaces unclear from source)
- `DTS.Viewer.TestSummaryList.ViewModel``ITestSummaryListViewModel`, `TestSummaryViewListModel`
- `Prism.Events``IEventAggregator`
- `System.Windows.Threading``Dispatcher`, `DispatcherPriority`
- `System.Windows``MessageBox`
- `System.IO``Directory`
- `System.Linq` — LINQ extension methods
### What depends on this module:
- Cannot be determined from this source file alone. The `Parent` property suggests consumption by `ITestSummaryListViewModel` implementations.
---
## 5. Gotchas
1. **Misleading XML documentation**: The `<summary>` for `GetTestSummary` states "Returns list of Test Definition" but the method returns `void`.
2. **Naming convention violation**: `_eventAggregator` uses an underscore prefix (conventionally indicating private fields) but is a public property.
3. **Fire-and-forget async pattern**: `GetTestSummary` dispatches work via `InvokeAsync` with no mechanism for callers to know when loading completes. The `IsBusy` flag and event publications are the only completion signals.
4. **Silent exception swallowing**: Lines 99-108 contain a try/catch with an empty catch block (`catch (Exception) { }`). The comment indicates this was added for a regression build to prevent crashes from a new feature (case 16158).
5. **Unimplemented property**: `IsSaved` is a get-only auto-property with no backing field assignment, meaning it always returns `false`.
6. **Hardcoded string literal**: The string `"ALL"` is used for `DataType` comparison in `DetermineTestsSelected` without a constant or enum.
7. **UI coupling in model**: The model directly shows a `MessageBox` on errors (line 113), violating separation of concerns.
8. **Case reference comments**: Multiple comments reference an internal manuscript system (e.g., `http://manuscript.dts.local/f/cases/28164/`) which are inaccessible outside the organization.

View File

@@ -0,0 +1,56 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestSummaryList/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T11:16:50.245640+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "3de23a946bdde4b4"
---
# Documentation: DTS.Viewer.TestSummaryList Assembly Configuration
## 1. Purpose
This file provides assembly-level metadata and configuration for the `DTS.Viewer.TestSummaryList` module (compiled as `DTS.Viewer.Test`). It is a standard .NET Framework `AssemblyInfo.cs` file that defines version information, COM visibility settings, and identification attributes. This module appears to be part of a larger DTS Viewer application, specifically handling test summary list functionality.
## 2. Public Interface
This file contains no public functions, classes, or methods. It consists entirely of assembly-level attributes:
| Attribute | Value |
|-----------|-------|
| `AssemblyTitle` | `"DTS.Viewer.Test"` |
| `AssemblyDescription` | `""` (empty) |
| `AssemblyConfiguration` | `""` (empty) |
| `AssemblyCompany` | `""` (empty) |
| `AssemblyProduct` | `"DTS.Viewer.Test"` |
| `AssemblyCopyright` | `"Copyright © 2017"` |
| `AssemblyTrademark` | `""` (empty) |
| `AssemblyCulture` | `""` (empty) |
| `ComVisible` | `false` |
| `Guid` | `"b2b2b862-1b93-476a-8246-91e1310c7ec7"` |
| `AssemblyVersion` | `"1.0.0.0"` |
| `AssemblyFileVersion` | `"1.0.0.0"` |
## 3. Invariants
- **COM Visibility**: All types in this assembly are not visible to COM components (`ComVisible(false)`). If COM interop is required, individual types must explicitly set `[ComVisible(true)]`.
- **Version Consistency**: Both `AssemblyVersion` and `AssemblyFileVersion` are set to `"1.0.0.0"` and must be updated together when versioning changes.
- **Assembly Identity**: The GUID `b2b2b862-1b93-476a-8246-91e1310c7ec7` uniquely identifies this assembly's type library if exposed to COM.
## 4. Dependencies
**This module depends on:**
- `System.Reflection` - For assembly metadata attributes
- `System.Runtime.CompilerServices` - For compiler-related attributes
- `System.Runtime.InteropServices` - For COM interop attributes
**What depends on this module:**
- Unclear from source alone. This is a configuration file; the actual module implementation would be in other source files within the `DTS.Viewer.TestSummaryList` project.
## 5. Gotchas
- **Naming Inconsistency**: The directory/module name is `DTS.Viewer.TestSummaryList`, but the `AssemblyTitle` and `AssemblyProduct` are set to `"DTS.Viewer.Test"`. This discrepancy may cause confusion when referencing the assembly or interpreting logs/diagnostics.
- **Empty Metadata Fields**: `AssemblyDescription`, `AssemblyCompany`, and `AssemblyConfiguration` are all empty strings, which may indicate incomplete documentation or placeholder values.
- **Legacy Project Format**: The presence of an explicit `AssemblyInfo.cs` file suggests this is using the older .NET Framework project style (pre-SDK-style projects), which may affect build tooling and migration paths.
- **Hardcoded Version**: The version `1.0.0.0` appears to be a placeholder that has not been updated since the copyright year of 2017.

View File

@@ -0,0 +1,129 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestSummaryList/Resources/StringResources.ja.Designer.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestSummaryList/Resources/TranslateExtension.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestSummaryList/Resources/StringResources.Designer.cs
generated_at: "2026-04-16T11:16:26.757827+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "ef8f2f0524698a0d"
---
# Documentation: DTS.Viewer.TestSummaryList.Resources
## 1. Purpose
This module provides localization/internationalization infrastructure for the TestSummaryList component of the DTS Viewer application. It enables XAML-based string resource lookups through a WPF markup extension (`TranslateExtension`) and exposes strongly-typed access to localized UI strings via the auto-generated `StringResources` class. The module supports the display of test summary information with sortable columns and metadata labels.
---
## 2. Public Interface
### TranslateExtension (DTS.Viewer.TestSummaryList namespace)
A WPF markup extension for resolving localized strings in XAML bindings.
```csharp
[MarkupExtensionReturnType(typeof(string))]
public class TranslateExtension : MarkupExtension
```
**Constructor:**
```csharp
public TranslateExtension(string key)
```
- Creates an instance with the specified resource key to look up.
**Method:**
```csharp
public override object ProvideValue(IServiceProvider serviceProvider)
```
- Returns the localized string for the stored key via `StringResources.ResourceManager.GetString(_key)`.
- Returns `#stringnotfound#` if `_key` is null or empty.
- Returns `#stringnotfound# {key}` if the key is valid but no resource is found.
---
### StringResources (DTS.Viewer.TestSummaryList.Resources namespace)
An internal, auto-generated strongly-typed resource class.
```csharp
internal class StringResources
```
**Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `ResourceManager` | `global::System.Resources.ResourceManager` (static) | Cached ResourceManager instance for the `DTS.Viewer.TestSummaryList.Resources.StringResources` resource bundle. |
| `Culture` | `global::System.Globalization.CultureInfo` (static) | Gets or sets the current thread's UI culture for resource lookups. |
**Localized String Properties (all `internal static string`):**
| Property | Default Value (from comments) |
|----------|-------------------------------|
| `Browse` | "Browse..." |
| `ChannelCount` | "Channels: " |
| `Description` | "Description: " |
| `FileDate` | "File Date: " |
| `FileDateAscending` | "File Date" |
| `FileDateDescending` | "File Date (Descending)" |
| `IdAscending` | "Test ID" |
| `IdDescending` | "Test ID (Descending)" |
| `Refresh` | "Refresh" |
| `SetupNameAscending` | "Test Setup" |
| `SetupNameDescending` | "Test Setup (Descending)" |
| `Sort` | "Sort: " |
| `TestID` | "Test ID: " |
| `TestSetup` | "Test Setup: " |
| `TimeStamp` | "TimeStamp: " |
| `TimeStampAscending` | "TimeStamp" |
| `TimeStampDescending` | "TimeStamp (Descending)" |
| `Type` | "Type: " |
---
## 3. Invariants
1. **Auto-generation constraint**: `StringResources` is auto-generated by `System.Resources.Tools.StronglyTypedResourceBuilder` (version 17.0.0.0). Manual edits will be lost upon regeneration.
2. **Non-null return guarantee**: `TranslateExtension.ProvideValue()` always returns a non-null string. It never returns null—missing keys produce error indicators.
3. **Error format for missing keys**: When a resource key is not found, the return value follows the pattern `#stringnotfound# {key}` where `{key}` is the requested key name.
4. **Empty key handling**: A null or empty `_key` returns exactly `#stringnotfound#` without a trailing key name.
5. **Resource manager identity**: The `ResourceManager` property always returns an instance tied to the resource name `"DTS.Viewer.TestSummaryList.Resources.StringResources"` within the current assembly.
---
## 4. Dependencies
### This module depends on:
- `System` (core types)
- `System.Windows.Markup` (`MarkupExtension`, `MarkupExtensionReturnTypeAttribute`)
- `System.Resources` (`ResourceManager`)
- `System.Globalization` (`CultureInfo`)
- `System.CodeDom.Compiler` (generated code attributes)
- `System.Diagnostics` (generated code attributes)
- `System.Runtime.CompilerServices` (generated code attributes)
- `System.ComponentModel` (`EditorBrowsableAttribute`)
### What depends on this module:
- **Inferred**: XAML files within the `DTS.Viewer.TestSummaryList` module that use `{local:Translate KeyName}` syntax for localized UI strings.
- **Inferred**: Code-behind files that access `StringResources.<PropertyName>` directly for programmatic string retrieval.
---
## 5. Gotchas
1. **Empty Japanese resource file**: `StringResources.ja.Designer.cs` is present but empty. Japanese localization may be incomplete or handled through a different mechanism (e.g., `.resx` file without a separate designer file).
2. **Fallback culture behavior unclear**: The source does not show explicit fallback logic. The actual fallback behavior (e.g., defaulting to English when a culture-specific resource is missing) depends on .NET's standard resource fallback process, which is not visible in this source.
3. **Internal visibility**: `StringResources` is marked `internal`, limiting direct programmatic access to code within the same assembly. External assemblies must use `TranslateExtension` or another exposed mechanism.
4. **Trailing colons in labels**: Several properties (`ChannelCount`, `Description`, `FileDate`, `Sort`, `TestID`, `TestSetup`, `TimeStamp`, `Type`) include trailing colons and spaces in their default values. These are label strings intended for UI pairing with values, not standalone text.
5. **Case-sensitive key lookup**: `TranslateExtension` passes the key directly to `ResourceManager.GetString()`. Key mismatches due to case sensitivity will result in "not found" errors rather than automatic correction.

View File

@@ -0,0 +1,79 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestSummaryList/View/TestSummaryView.xaml.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestSummaryList/View/TestSummaryListView.xaml.cs
generated_at: "2026-04-16T11:17:15.115446+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "a0b85470cc6f6727"
---
# Documentation: DTS.Viewer.TestSummaryList Views
## 1. Purpose
This module provides WPF view components for displaying and interacting with test summaries in the DTS Viewer application. It contains two partial views—`TestSummaryView` and `TestSummaryListView`—both implementing `ITestSummaryListView`. The `TestSummaryListView` specifically adds keyboard interaction support for toggling test selection via the Space key. These views serve as the presentation layer for test summary data within a larger modular viewer architecture.
---
## 2. Public Interface
### `TestSummaryView` (class)
**Namespace:** `DTS.Viewer.TestSummaryList`
**Implements:** `ITestSummaryListView`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `public TestSummaryView()` | Initializes the view component by calling `InitializeComponent()`. |
---
### `TestSummaryListView` (class)
**Namespace:** `DTS.Viewer.TestSummaryList`
**Implements:** `ITestSummaryListView`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `public TestSummaryListView()` | Initializes the view component by calling `InitializeComponent()`. |
| `TestSummary_KeyUp` | `private void TestSummary_KeyUp(object sender, KeyEventArgs e)` | Event handler that toggles the `IsSelected` property on a `TestSummary` object when the Space key is released, provided the `sender` is a `ListView` with a `TestSummary` as its `SelectedItem`. |
---
## 3. Invariants
- Both view classes implement `ITestSummaryListView` from `DTS.Common.Interface`.
- `TestSummaryListView.TestSummary_KeyUp` will only modify `IsSelected` if:
- The `sender` can be cast to a `ListView`.
- The `ListView.SelectedItem` can be cast to a `TestSummary` type.
- The pressed key is `Key.Space`.
- If any of the above conditions fail, `e.Handled` is set to `false`; otherwise, it is set to `true`.
- The `TestSummary` class (from `DTS.Common.Classes.Viewer.TestMetadata`) must have a public `IsSelected` property that is boolean-settable.
---
## 4. Dependencies
### This module depends on:
| Dependency | Usage |
|------------|-------|
| `System.Windows` | WPF framework (`FrameworkElement` base class via partial class) |
| `System.Windows.Controls` | `ListView` control used in `TestSummary_KeyUp` |
| `System.Windows.Input` | `Key` enum and `KeyEventArgs` for keyboard handling |
| `DTS.Common.Interface` | `ITestSummaryListView` interface contract |
| `DTS.Common.Classes.Viewer.TestMetadata` | `TestSummary` data class |
| `DTS.Common.Interface.TestDefinition` | Imported in `TestSummaryListView.xaml.cs` but **not visibly used** in the code-behind |
### What depends on this module:
- **Unclear from source alone.** Consumers would be modules that reference `ITestSummaryListView` or instantiate these views directly (likely via dependency injection or XAML composition in a parent view).
---
## 5. Gotchas
1. **Misleading XML comment in `TestSummaryView.xaml.cs`:** The documentation comment states "Interaction logic for TestListView.xaml" but the class is named `TestSummaryView`. This appears to be a copy-paste error from another view.
2. **Unused import:** `DTS.Common.Interface.TestDefinition` is imported in `TestSummaryListView.xaml.cs` but not referenced in the code-behind. It may be used in the XAML file (not provided) or is dead code.
3. **Namespace directive:** The `// ReSharper disable CheckNamespace` directive in `TestSummaryListView.xaml.cs` suggests the file location may not match the declared namespace, or ReSharper was producing warnings. The actual namespace discrepancy is not apparent from the source alone.
4. **Two classes implementing the same interface:** Both `TestSummaryView` and `TestSummaryListView` implement `ITestSummaryListView`. The relationship between these two views (inheritance, alternative implementations, or deprecated code) is unclear from the source alone.

View File

@@ -0,0 +1,178 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestSummaryList/ViewModel/TestSummaryViewModel.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.TestSummaryList/ViewModel/TestSummaryViewListModel.cs
generated_at: "2026-04-16T11:16:50.405785+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "b27cef2360f72751"
---
# Documentation: TestSummaryList ViewModels
## 1. Purpose
This module provides two ViewModel implementations (`TestSummaryViewModel` and `TestSummaryViewListModel`) for managing and displaying test summary lists within a modular WPF application built on the Prism framework. These ViewModels serve as intermediaries between test summary data models and views, handling user interactions, data folder/file selection, filtering, sorting, and event-based communication with other application components via `IEventAggregator`. The module appears to support a data viewer scenario where users can browse, filter, and select test summaries from DTS files.
---
## 2. Public Interface
### TestSummaryViewModel
**Constructor:**
```csharp
public TestSummaryViewModel(ITestSummaryListView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
```
Initializes the ViewModel, sets the view's DataContext, creates interaction requests, and subscribes to `RaiseNotification` and `DataFolderChangedEvent` events.
**Methods:**
| Method | Signature | Description |
|--------|-----------|-------------|
| `Initialize` | `void Initialize()` | Empty override. |
| `Initialize` | `void Initialize(object parameter)` | Sets `Parent` property from parameter (cast to `IBaseWindowModel`). |
| `Activated` | `void Activated()` | **Throws `NotImplementedException`.** |
| `Cleanup` | `void Cleanup()` | **Throws `NotImplementedException`.** |
| `CleanupAsync` | `Task CleanupAsync()` | **Throws `NotImplementedException`.** |
| `InitializeAsync` | `Task InitializeAsync()` | **Throws `NotImplementedException`.** |
| `InitializeAsync` | `Task InitializeAsync(object parameter)` | **Throws `NotImplementedException`.** |
| `PublishSelectedTestSummaryList` | `void PublishSelectedTestSummaryList()` | Publishes `TestSummaryChangeNotification` and `TestSelectedChangedEvent` events with current selection. |
**Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `TestSummaryListView` | `ITestSummaryListView` | The associated view instance. |
| `NotificationRequest` | `InteractionRequest<Notification>` | Interaction request for notifications. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | Interaction request for confirmations. |
| `ContextNavigationRegion` | `object` | Gets/sets content of `TestListRegion` on the view. |
| `SelectedTestSummary` | `TestSummary` | Currently selected test summary. |
| `SelectedTestSummaryList` | `List<ITestSummary>` | List of selected test summaries. |
| `TestSummaryList` | `ObservableCollection<ITestSummary>` | Collection of all test summaries. |
| `HeaderInfo` | `string` | Returns `"TestSummaryRegion"`. |
| `IsBusy` | `bool` | Busy indicator state. |
| `IsDirty` | `bool` | Dirty state flag. |
| `IsNavigationIncluded` | `bool` | Navigation inclusion flag. |
---
### TestSummaryViewListModel
**Constructor:**
```csharp
public TestSummaryViewListModel(ITestSummaryListView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
```
Initializes the ViewModel, sets the view's DataContext, creates interaction requests, and stores dependencies.
**Methods:**
| Method | Signature | Description |
|--------|-----------|-------------|
| `Initialize` | `void Initialize()` | Empty override. |
| `Initialize` | `void Initialize(object parameter)` | Sets `Parent`, initializes `FilterView`, attaches collection change handlers, and subscribes to events. |
| `Activated` | `void Activated()` | Publishes `FilterParameterChangedEvent` with empty parameter. |
| `Cleanup` | `void Cleanup()` | Clears all test summary collections, resets `SelectedTestSummary`, and publishes selection change events. |
| `PublishSelectedTestSummaryList` | `void PublishSelectedTestSummaryList()` | Publishes `TestSummaryChangeNotification`, `TestSummaryCountNotification`, and `ResetZoomChangedEvent` events. |
| `OnFilterChanged` | `void OnFilterChanged(FilterParameterArgs args)` | Filters `FilteredTestSummaryList` based on `SetupName`, `Id`, or `Description` containing the parameter string (case-insensitive). |
| `RefreshDataFolder` | `void RefreshDataFolder()` | Publishes `DataFolderChangedEvent` via dispatcher with current selected folder. |
| `SelectDataFolder` | `void SelectDataFolder()` | Opens `OpenFileDialog` for DTS files and publishes `DataFileSelectedEvent` on selection. |
**Properties:**
| Property | Type | Description |
|----------|------|-------------|
| `FilterView` | `IFilterView` | Filter view instance resolved from container. |
| `View` | `ITestSummaryListView` | The associated view instance. |
| `NotificationRequest` | `InteractionRequest<Notification>` | Interaction request for notifications. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | Interaction request for confirmations. |
| `ContextNavigationRegion` | `object` | Gets/sets DataContext of `TestListRegion` on the view. |
| `IsFilterEnabled` | `bool` | Indicates if filtering is enabled (true when `TestSummaryList` has items). |
| `SelectedTestSummary` | `TestSummary` | Currently selected test summary. |
| `SelectedTestSummaryList` | `List<ITestSummary>` | List of selected test summaries. |
| `TestSummaryList` | `ObservableCollection<ITestSummary>` | Collection of all test summaries; setter updates `IsFilterEnabled` and `FilteredTestSummaryList`. |
| `FilteredTestSummaryList` | `ObservableCollection<ITestSummary>` | Filtered view of test summaries. |
| `HeaderInfo` | `string` | Returns `"TestSummaryRegion"`. |
| `IsBusy` | `bool` | Busy indicator state. |
| `IsDirty` | `bool` | Dirty state flag. |
| `IsNavigationIncluded` | `bool` | Navigation inclusion flag. |
| `SelectedDataFolder` | `string` | Selected data folder path; setter publishes `DataFolderChangedEvent`. |
| `SelectedDataFile` | `string` | Selected data file path; setter publishes `DataFolderChangedEvent`. |
| `SortableAttributes` | `List<string>` | List of localized sortable attribute names. |
| `SelectedSortIndex` | `int` | Index of selected sort attribute; setter triggers `SortTestSummaryList()`. |
**Commands:**
| Command | Type | Description |
|---------|------|-------------|
| `RefreshDataFolderCommand` | `DelegateCommand` | Refreshes the current data folder. |
| `SelectDataFolderCommand` | `DelegateCommand` | Opens file dialog to select a DTS file. |
**Nested Types:**
- `SortableAttribute` (enum): `TimeStampDescending`, `Timestamp`, `FileDateDescending`, `FileDate`, `IdDescending`, `Id`, `TestSetupDescending`, `TestSetup`
- `SortableAttributeHelper` (class): Helper for converting `SortableAttribute` to localized string via `StringResources.ResourceManager`.
---
## 3. Invariants
1. **Event Subscription Timing**: Both ViewModels subscribe to events in their constructors. `TestSummaryViewListModel` additionally calls `Subscribe()` during `Initialize(object parameter)`.
2. **Parent Parameter Casting**:
- `TestSummaryViewModel.Initialize(object parameter)` casts to `IBaseWindowModel`
- `TestSummaryViewListModel.Initialize(object parameter)` casts to `IBaseViewModel`
3. **Collection Synchronization**: In `TestSummaryViewListModel`, setting `TestSummaryList` automatically updates `FilteredTestSummaryList` and `IsFilterEnabled`.
4. **Property Change Propagation**: `TestSummaryViewListModel.TestSummaryList_CollectionChanged` attaches/detaches `PropertyChanged` handlers to items implementing `INotifyPropertyChanged`.
5. **Sorting Behavior**: `SortTestSummaryList()` clears and repopulates `FilteredTestSummaryList` in-place based on `SelectedSortIndex`.
6. **Filter Matching**: `OnFilterChanged` performs case-insensitive `Contains` matching on `SetupName`, `Id`, and `Description` fields.
---
## 4. Dependencies
### External Dependencies (from imports):
- **Prism Framework**: `Microsoft.Practices.Prism.Events`, `Microsoft.Practices.Prism.Interactivity.InteractionRequest`, `Microsoft.Practices.Prism.Regions`, `Prism.Events`, `Prism.Regions`, `Prism.Commands`
- **Unity**: `Microsoft.Practices.Unity`, `Unity`
- **System.Windows.Forms**: Used for `OpenFileDialog` in `TestSummaryViewListModel.SelectDataFolder()`
### Internal Dependencies (DTS.* namespaces):
- `DTS.Common.Base` (`BaseViewModel<T>`)
- `DTS.Common.Classes.TestMetadata` (`TestSummary`)
- `DTS.Common.Classes.Viewer.TestMetadata`
- `DTS.Common.Events` (`RaiseNotification`, `DataFolderChangedEvent`, `TestSummaryChangeNotification`, `TestSelectedChangedEvent`, `ShowStatus`, `FilterParameterChangedEvent`, `RefreshTestRequestEvent`, `TestSummaryCountNotification`, `ResetZoomChangedEvent`, `DataFileSelectedEvent`)
- `DTS.Common.Interface` (`IBaseWindowModel`, `IBaseViewModel`, `IFilterView`, `IFilterViewModel`)
- `DTS.Common.Interface.TestDefinition` (`ITestSummary`, `ITestSummaryListViewModel`, `ITestSummaryListView`)
- `DTS.Common.Interactivity`
- `DTS.Viewer.TestSummaryList.Model` (`TestSummaryModel`)
- `DTS.Viewer.TestSummaryList.Resources` (`StringResources`)
### Dependents:
- Views: `TestSummaryView`, `TestSummaryListView` (referenced via casting in `ContextNavigationRegion` properties)
---
## 5. Gotchas
1. **Stale XML Documentation**: The constructor XML comment in `TestSummaryViewModel` states "Creates a new instance of the TechnologyDoFrontEditViewModel" — this appears to be a copy-paste error from another ViewModel.
2. **NotImplementedException Methods**: In `TestSummaryViewModel`, the following methods throw `NotImplementedException`:
- `Activated()`
- `Cleanup()`
- `CleanupAsync()`
- `InitializeAsync()`
- `InitializeAsync(object parameter)`
These indicate incomplete implementation or placeholder code.
3. **Member Hiding with `new` Keyword**: Both ViewModels use `new` to hide inherited members (`PropertyChanged`, `OnPropertyChanged`, `IsBusy`, `IsDirty`, `IsNavigationIncluded`). This can lead to unexpected behavior when casting to base types.
4. **Inconsistent Event Signatures**:
- `TestSummaryViewModel.OnDataFolderChanged(string path)` takes a `string` parameter
- `TestSummaryViewListModel.OnDataFolderChanged(DataFolderSelectionArg arg)` takes a `DataFolderSelectionArg` parameter
Both subscribe to `DataFolderChangedEvent`, suggesting the event payload type changed or the ViewModels are used in different contexts.
5. **WinForms Interop in WPF**: `TestSummaryViewListModel.SelectDataFolder()` uses `System.Windows.Forms.OpenFileDialog` rather than a WPF dialog, requiring WinForms integration.
6. **Internal Field Assignment**: Both ViewModels create `TestSummaryModel` instances and set the private `_eventAggregator` field directly (e.g., `td._eventAggregator = _eventAggregator`), which bypasses encapsulation and suggests tight coupling.
7. **Typo in Property Name**: `TestSummaryViewListModel._selctedSortIndex` (missing 'e' in "selected") — minor but could cause confusion during debugging.

View File

@@ -0,0 +1,94 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ViewerSettings/ViewerSettingsModule.cs
generated_at: "2026-04-16T11:05:22.275750+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "9f0f5c6b474b7ca8"
---
# Documentation: ViewerSettingsModule
## 1. Purpose
This module serves as the Prism module definition for the ViewerSettings feature within the DTS Viewer application. It is responsible for registering the ViewerSettings View and ViewModel with the Unity dependency injection container, and providing assembly-level metadata (name, image, group, and region) that enables the main application to discover and display this module as an available component. The module belongs to the "Viewer" assembly group and targets the "ViewerSettingsRegion" for UI composition.
---
## 2. Public Interface
### `ViewerSettingsModule` (class)
Implements `Prism.Modularity.IModule`. The primary module entry point for the ViewerSettings feature.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `ViewerSettingsModule(IUnityContainer unityContainer)` | Accepts a Unity container instance via dependency injection and stores it in `_unityContainer`. |
| `RegisterTypes` | `void RegisterTypes(IContainerRegistry containerRegistry)` | Calls `Initialize()` to perform type registrations. |
| `OnInitialized` | `void OnInitialized(IContainerProvider containerProvider)` | Empty implementation; no post-registration logic executed. |
| `Initialize` | `void Initialize()` | Registers `IViewerSettingsView``ViewerSettingsView` and `IViewerSettingsViewModel``ViewerSettingsViewModel` with Unity. A commented-out registration for `IViewerSettingsModel` exists but is not active. |
### `ViewerSettingsModuleNameAttribute` (class)
Extends `DTS.Common.Interface.TextAttribute`. Assembly-level attribute providing the module's name.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `ViewerSettingsModuleNameAttribute()` | Default constructor; sets `AssemblyName` to `AssemblyNames.ViewerSettings.ToString()`. |
| Constructor | `ViewerSettingsModuleNameAttribute(string s)` | Overload accepting a string parameter (unused). |
| `AssemblyName` | `override string AssemblyName { get; }` | Returns `AssemblyNames.ViewerSettings.ToString()`. |
| `GetAttributeType` | `override Type GetAttributeType()` | Returns `typeof(TextAttribute)`. |
| `GetAssemblyName` | `override string GetAssemblyName()` | Returns the `AssemblyName` property value. |
### `ViewerSettingsModuleImageAttribute` (class)
Extends `DTS.Common.Interface.ImageAttribute`. Assembly-level attribute providing the module's image, name, group, and region metadata.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `ViewerSettingsModuleImageAttribute()` | Default constructor; initializes `_img` via `AssemblyInfo.GetImage()`. |
| Constructor | `ViewerSettingsModuleImageAttribute(string s)` | Overload accepting a string parameter (unused). |
| `AssemblyImage` | `override BitmapImage AssemblyImage { get; }` | Lazy-loads and returns the module's image via `AssemblyInfo.GetImage(AssemblyNames.ViewerSettings.ToString())`. |
| `AssemblyName` | `override string AssemblyName { get; }` | Returns `AssemblyNames.ViewerSettings.ToString()`. |
| `AssemblyGroup` | `override string AssemblyGroup { get; }` | Returns `eAssemblyGroups.Viewer.ToString()`. |
| `AssemblyRegion` | `override eAssemblyRegion AssemblyRegion { get; }` | Returns `eAssemblyRegion.ViewerSettingsRegion`. |
| `GetAttributeType` | `override Type GetAttributeType()` | Returns `typeof(ImageAttribute)`. |
| `GetAssemblyImage` | `override BitmapImage GetAssemblyImage()` | Returns `AssemblyImage`. |
| `GetAssemblyName` | `override string GetAssemblyName()` | Returns `AssemblyName`. |
| `GetAssemblyGroup` | `override string GetAssemblyGroup()` | Returns `AssemblyGroup`. |
| `GetAssemblyRegion` | `override eAssemblyRegion GetAssemblyRegion()` | Returns `AssemblyRegion`. |
---
## 3. Invariants
- **Module Registration**: `IViewerSettingsView` must always resolve to `ViewerSettingsView`, and `IViewerSettingsViewModel` must always resolve to `ViewerSettingsViewModel` after the module is loaded.
- **Assembly Attributes**: Both `ViewerSettingsModuleNameAttribute` and `ViewerSettingsModuleImageAttribute` are applied at assembly level with `AllowMultiple = false`, ensuring exactly one instance of each per assembly.
- **Region Assignment**: The module is always associated with `eAssemblyRegion.ViewerSettingsRegion`.
- **Group Assignment**: The module always belongs to `eAssemblyGroups.Viewer`.
---
## 4. Dependencies
### This Module Depends On:
- `Prism.Modularity``IModule` interface for module lifecycle.
- `Prism.Ioc``IContainerProvider`, `IContainerRegistry` for DI registration.
- `Unity``IUnityContainer` for Unity-specific DI operations.
- `System.Windows.Media.Imaging``BitmapImage` for module imagery.
- `DTS.Common``AssemblyNames` enum (inferred from usage).
- `DTS.Common.Interface``TextAttribute`, `ImageAttribute` base classes; `eAssemblyGroups`, `eAssemblyRegion` enums; `AssemblyInfo` static class (inferred from usage).
### What Depends On This Module:
- **Main DTS Viewer Application** — Loads this module dynamically via Prism's module catalog; uses the assembly attributes to display the module in available components list and navigate to the appropriate region.
---
## 5. Gotchas
1. **Misleading Singleton Comment**: The comment on line 35 states "Register View & View-Model... as a singleton," but `_unityContainer.RegisterType<TFrom, TTo>()` without an explicit `ContainerControlledLifetimeManager` registers types as **transient**, not singleton. Either the comment is incorrect, or the implementation is missing the lifetime manager.
2. **Non-standard Initialization Pattern**: `Initialize()` is invoked from `RegisterTypes()`, while `OnInitialized()` is empty. The typical Prism pattern is to register types in `RegisterTypes()` and perform post-registration initialization in `OnInitialized()`. This conflation may cause confusion.
3. **Unused Constructor Parameter**: Both attribute classes have constructors accepting a `string s` parameter that is never used. This appears to be a requirement for attribute syntax compatibility, but its purpose is unclear from source alone.
4. **Redundant Image Initialization**: In `ViewerSettingsModuleImageAttribute`, `_img` is assigned in both the constructor and the `AssemblyImage` property getter. The property getter reassigns `_img` on every access, which is redundant after the first call.
5. **Commented-Out Model Registration**: Line 39 contains a commented registration for `IViewerSettingsModel`. It is unclear whether this represents incomplete work, a deprecated pattern, or intentional removal.

View File

@@ -0,0 +1,44 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ViewerSettings/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T11:12:27.563991+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "aa69b1de52a95e40"
---
# Documentation for AssemblyInfo.cs
## 1. Purpose
This file provides assembly-level metadata configuration for the `DTS.Viewer.ViewerSettings` module. It defines the manifest attributes used by the .NET runtime and hosting environment to identify, version, and configure the compiled assembly. It exists to establish the module's identity, version number, and COM visibility settings within the larger DTS Viewer application architecture.
## 2. Public Interface
This source file does not contain public classes, methods, or functions. It applies assembly-level attributes that affect the compiled output (`DTS.Viewer.ViewerSettings.dll`).
The following attributes are defined:
* **`AssemblyTitle`**: Set to `"DTS.Viewer.ViewerSettings"`.
* **`AssemblyDescription`**: Set to an empty string.
* **`AssemblyConfiguration`**: Set to an empty string.
* **`AssemblyCompany`**: Set to an empty string.
* **`AssemblyProduct`**: Set to `"DTS.Viewer.ViewerSettings"`.
* **`AssemblyCopyright`**: Set to `"Copyright © 2019"`.
* **`AssemblyTrademark`**: Set to an empty string.
* **`AssemblyCulture`**: Set to an empty string (indicates the assembly is culture-neutral).
* **`ComVisible`**: Set to `false`. This prevents types in this assembly from being visible to COM components.
* **`Guid`**: Set to `"4733690a-cb08-4c2e-853a-9339be13ac28"`. This acts as the ID for the type library if the assembly is exposed to COM.
* **`AssemblyVersion`**: Set to `"1.0.0.0"`.
* **`AssemblyFileVersion`**: Set to `"1.0.0.0"`.
## 3. Invariants
* **Version Consistency**: Both `AssemblyVersion` and `AssemblyFileVersion` are currently synchronized at `1.0.0.0`.
* **COM Visibility**: The assembly is explicitly non-visible to COM (`ComVisible(false)`). This must be changed at the type level if specific types need COM exposure later.
* **Culture Neutrality**: The `AssemblyCulture` attribute is empty, implying this is a neutral/satellite assembly rather than a localized resource assembly.
## 4. Dependencies
* **Internal Dependencies**: This file imports `System.Reflection`, `System.Runtime.CompilerServices`, and `System.Runtime.InteropServices`.
* **System Context**: This file configures the `DTS.Viewer.ViewerSettings` assembly. Based on the file path, this assembly is part of the `DTS.Viewer.Modules` collection, suggesting it is a submodule consumed by the main `DTS Viewer` application. The specific runtime dependencies of the code within this assembly cannot be determined from this file alone.
## 5. Gotchas
* **SDK-Style Project Compatibility**: If this project is migrated to the modern SDK-style project format (typically .NET Core or .NET 5+), the attributes defined here will conflict with auto-generated assembly information. This would result in build errors (duplicate attributes) unless `<GenerateAssemblyInfo>false</GenerateAssemblyInfo>` is added to the project file.
* **Missing Metadata**: `AssemblyDescription`, `AssemblyCompany`, and `AssemblyConfiguration` are empty strings. This missing metadata may appear in file properties dialogs or assembly inspection tools as blank fields.

View File

@@ -0,0 +1,92 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ViewerSettings/Resources/TranslateExtension.cs
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ViewerSettings/Resources/StringResources.Designer.cs
generated_at: "2026-04-16T11:12:19.064013+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "b58f3ee343f377b9"
---
# Documentation: DTS.Viewer.ViewerSettings.Resources
## 1. Purpose
This module provides localization infrastructure for the DTS Viewer settings UI. It consists of two components: `TranslateExtension`, a WPF `MarkupExtension` that enables XAML bindings to localized strings, and `StringResources`, an auto-generated strongly-typed resource class that wraps a `.resx` file containing the actual localized string values. Together, they allow XAML markup to reference localized strings declaratively (e.g., `{local:Translate SomeKey}`) while centralizing string management through the .NET resource system.
---
## 2. Public Interface
### `TranslateExtension` (public class)
**Namespace:** `DTS.Viewer.ViewerSettings`
**Base Class:** `System.Windows.Markup.MarkupExtension`
**Attribute:** `[MarkupExtensionReturnType(typeof(string))]`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `TranslateExtension(string key)` | Initializes the extension with the resource key to look up. Stores the key in a readonly field `_key`. |
| `ProvideValue` | `public override object ProvideValue(IServiceProvider serviceProvider)` | Returns the localized string for `_key` from `StringResources.ResourceManager`. Returns `NotFound` constant if `_key` is null or empty. Returns `NotFound + " " + _key` if the key is not found in resources. |
**Constants:**
- `private const string NotFound = "#stringnotfound#"` — Fallback value returned when translation cannot be resolved.
---
### `StringResources` (internal class)
**Namespace:** `DTS.Viewer.ViewerSettings.Resources`
**Attributes:** `[GeneratedCode]`, `[DebuggerNonUserCode]`, `[CompilerGenerated]`
| Member | Signature | Description |
|--------|-----------|-------------|
| `ResourceManager` | `internal static global::System.Resources.ResourceManager ResourceManager { get; }` | Lazily-initialized, cached `ResourceManager` instance for the `DTS.Viewer.ViewerSettings.Resources.StringResources` resource bundle. |
| `Culture` | `internal static global::System.Globalization.CultureInfo Culture { get; set; }` | Overrides the current thread's `CurrentUICulture` for resource lookups via this class. Can be set to change localization at runtime. |
| `CalibrationBehavior_LinearIfAvailable` | `internal static string CalibrationBehavior_LinearIfAvailable { get; }` | Localized string: "Use the linear sensitivity, if available." |
| `CalibrationBehavior_NonLinearIfAvailable` | `internal static string CalibrationBehavior_NonLinearIfAvailable { get; }` | Localized string: "Use the non-linear sensitivity, if available." |
| `CalibrationBehavior_UseBothIfAvailable` | `internal static string CalibrationBehavior_UseBothIfAvailable { get; }` | Localized string: "Use both sensitivities, if available, as separate channels." |
| `CalibrationBehaviorText` | `internal static string CalibrationBehaviorText { get; }` | Localized string: "Calibration Behavior". |
---
## 3. Invariants
1. **Key immutability:** `_key` in `TranslateExtension` is assigned once in the constructor and is readonly; it cannot be changed after instantiation.
2. **Non-null return guarantee:** `TranslateExtension.ProvideValue` always returns a non-null `string` — either the localized value, the `NotFound` constant, or `NotFound + " " + _key`.
3. **ResourceManager singleton pattern:** `StringResources.ResourceManager` is lazily initialized on first access and cached; subsequent accesses return the same instance.
4. **Thread-safety of ResourceManager initialization:** The getter checks for null using `object.ReferenceEquals(resourceMan, null)` before creating a new `ResourceManager`. **Note:** This pattern is not thread-safe; race conditions could result in multiple `ResourceManager` instances being created.
5. **Resource key existence:** `StringResources` property getters pass `resourceCulture` (which may be null) to `ResourceManager.GetString`, defaulting to the current thread's `CurrentUICulture` when null.
---
## 4. Dependencies
### This module depends on:
- `System` — Core .NET types
- `System.Windows.Markup``MarkupExtension` base class and `MarkupExtensionReturnTypeAttribute`
- `System.Resources``ResourceManager` for resource lookup
- `System.Globalization``CultureInfo` for localization
- `System.CodeDom.Compiler`, `System.Diagnostics`, `System.Runtime.CompilerServices` — Attributes for generated code (auto-generated dependency)
- **External resource file:** `StringResources.resx` (implied by the designer file; not included in source but required at runtime)
### What depends on this module:
- **Cannot be determined from source alone.** The `TranslateExtension` is designed for XAML consumption within the `DTS.Viewer.ViewerSettings` namespace, but no consumers are shown in the provided files.
---
## 5. Gotchas
1. **Different error formats for different failure modes:** A null/empty key returns `"#stringnotfound#"` alone, while a valid but missing key returns `"#stringnotfound# {key}"`. This distinction can be used for debugging but may cause inconsistent UI display if not handled upstream.
2. **StringResources is internal:** The class is marked `internal`, so it cannot be accessed outside the `DTS.Viewer.ViewerSettings.Resources` namespace's assembly. `TranslateExtension` works around this by accessing `StringResources.ResourceManager` directly.
3. **Auto-generated file warning:** `StringResources.Designer.cs` is tool-generated. Manual edits will be lost when the `.resx` file is modified and the designer regenerates. The actual string values live in `StringResources.resx`, which is not included in the provided source.
4. **Thread-safety concern:** The `ResourceManager` property getter uses a non-atomic null check pattern that is not thread-safe. In multi-threaded scenarios, two threads could simultaneously pass the null check and create separate `ResourceManager` instances. While likely harmless in practice (the ResourceManager itself is thread-safe), this violates the singleton intent.
5. **Culture must be set explicitly on StringResources:** Setting `Thread.CurrentUICulture` will NOT affect `StringResources` lookups if `StringResources.Culture` has been explicitly set to a non-null value. Consumers must either leave `StringResources.Culture` as null (to inherit thread culture) or set it explicitly.

View File

@@ -0,0 +1,40 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ViewerSettings/View/ViewerSettingsView.xaml.cs
generated_at: "2026-04-16T11:12:48.949292+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "499d220096c49a25"
---
# Documentation: ViewerSettingsView.xaml.cs
## 1. Purpose
This file defines the code-behind class `ViewerSettingsView` for a WPF `UserControl` within the `DTS.Viewer.ViewerSettings` namespace. It serves as the visual interface component for viewer configuration settings. The class implements the `IViewerSettingsView` interface, suggesting it is part of a larger architectural pattern (likely MVVM) where the view is decoupled from core application logic via the `DTS.Common.Interface` contract.
## 2. Public Interface
### Class: `ViewerSettingsView`
**Inherits from:** Unspecified base class (implicit WPF `UserControl` via `InitializeComponent`).
**Implements:** `DTS.Common.Interface.IViewerSettingsView`
#### Constructor: `ViewerSettingsView()`
* **Signature:** `public ViewerSettingsView()`
* **Behavior:** Initializes the component. It invokes the standard WPF `InitializeComponent()` method, which loads the XAML markup defined in the associated `.xaml` file for this view.
## 3. Invariants
* **Initialization:** The `InitializeComponent()` method is called exactly once upon instantiation. This is a strict requirement for WPF user controls to correctly parse the XAML and build the visual tree.
* **Interface Compliance:** As this class implements `IViewerSettingsView`, it must fulfill any contract defined by that interface (e.g., specific properties or methods), though no explicit interface implementations are visible in this specific source file.
## 4. Dependencies
* **Internal Dependencies:**
* `DTS.Common.Interface`: Used for the `IViewerSettingsView` interface.
* **External Dependencies:**
* `System.Windows.Controls`: Used for the base `UserControl` functionality (implied).
* Standard WPF namespaces (`System.Windows`, etc.): Referenced for UI elements and logic.
* **Associated Files:**
* This is a code-behind file; it is inextricably linked to `ViewerSettingsView.xaml`, which contains the actual UI layout.
## 5. Gotchas
* **Missing Interface Implementation Details:** The source file shows the class implements `IViewerSettingsView`, but no explicit implementation of interface members (properties or methods) is present in the code. It is unclear from this source alone whether the interface is empty (a marker interface) or if the implementation is expected to be provided elsewhere (e.g., via XAML bindings or partial class definitions).
* **Unused Imports:** The file imports several namespaces (e.g., `System.Linq`, `System.Threading.Tasks`, `System.Windows.Shapes`) that are not utilized in the visible code. This suggests the file may have been generated via a template and not cleaned up, or logic was removed without removing the imports.

View File

@@ -0,0 +1,126 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.ViewerSettings/ViewModel/ViewerSettingsViewModel.cs
generated_at: "2026-04-16T11:11:45.719644+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "f93455d3d5a535ba"
---
# Documentation: ViewerSettingsViewModel
## 1. Purpose
`ViewerSettingsViewModel` is a Prism-based ViewModel responsible for managing viewer configuration settings within the DTS Viewer application. It provides UI binding for calibration behavior selection, handles visibility state for settings panels, and facilitates decoupled communication with other system components via event aggregation. The class serves as the data context for `IViewerSettingsView` and participates in the application's navigation/region management infrastructure.
---
## 2. Public Interface
### Constructor
```csharp
public ViewerSettingsViewModel(
IViewerSettingsView view,
IRegionManager regionManager,
IEventAggregator eventAggregator,
IUnityContainer unityContainer)
```
Initializes the ViewModel, sets the View's DataContext to itself, and creates `NotificationRequest` and `ConfirmationRequest` instances.
---
### Properties
| Property | Type | Description |
|----------|------|-------------|
| `View` | `IViewerSettingsView` | Gets/sets the associated view interface. |
| `Parent` | `IBaseViewModel` | Gets/sets the parent ViewModel, set during initialization with parameter. |
| `NotificationRequest` | `InteractionRequest<Notification>` | Interaction request for notification dialogs. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | Interaction request for confirmation dialogs (declared with `new` keyword). |
| `HeaderInfo` | `string` | Returns `"SettingsRegion"`. |
| `IsBusy` | `bool` | Busy state indicator (declared with `new` keyword). |
| `IsDirty` | `bool` | Dirty state flag (declared with `new` keyword). |
| `IsNavigationIncluded` | `bool` | Navigation inclusion flag (declared with `new` keyword). |
| `CalibrationBehaviorSettingVisibility` | `Visibility` | Controls visibility of calibration behavior setting UI. Publishes `ViewerSettingsVisibilityChangedEvent` when changed. |
| `OverallSettingsVisibility` | `Visibility` | Read-only computed property. Returns `Visibility.Visible` if `CalibrationBehaviorSettingVisibility` is visible; otherwise `Visibility.Collapsed`. |
| `AvailableCalibrationBehaviors` | `DisplayedCalibrationBehavior[]` | Lazily-initialized, thread-safe array of three options: `_linearIfAvail`, `_nonLinearIfAvail`, `_useBothIfAvail`. |
| `CalibrationBehaviorSetting` | `DisplayedCalibrationBehavior` | Gets/sets the selected calibration behavior. Publishes `CalibrationBehaviorSettingChangedEvent` on change. |
---
### Methods
```csharp
public override void Initialize()
```
Empty override—no behavior.
```csharp
public override void Initialize(object parameter)
```
Sets `Parent` to the provided parameter (cast to `IBaseViewModel`) and calls `Subscribe()`.
```csharp
public void PublishChanges()
```
Empty method body—behavior unclear from source.
---
### Events
```csharp
public new event PropertyChangedEventHandler PropertyChanged
```
Declared with `new` keyword, hiding the base class event.
---
## 3. Invariants
- **Default Calibration Behavior**: `_calibrationBehaviorSetting` is initialized to `CalibrationBehaviors.NonLinearIfAvailable`.
- **Visibility Cascade**: When any property ending in `"Visibility"` (except `"OverallSettingsVisibility"`) changes, `OnPropertyChanged` automatically triggers a notification for `"OverallSettingsVisibility"`.
- **Thread Safety**: `AvailableCalibrationBehaviors` uses a lock (`MyLock`) to ensure thread-safe lazy initialization.
- **Event Subscription**: `Subscribe()` is called only from `Initialize(object parameter)`, requiring a non-null parameter for event subscriptions to be registered.
- **OverallSettingsVisibility Logic**: Always mirrors `CalibrationBehaviorSettingVisibility`—there is no scenario where they differ.
---
## 4. Dependencies
### This Module Depends On
| Namespace | Type(s) Used |
|-----------|--------------|
| `DTS.Common.Base` | `BaseViewModel<T>` |
| `DTS.Common.Classes.Sensors` | `DisplayedCalibrationBehavior` |
| `DTS.Common.Enums.Sensors` | `CalibrationBehaviors` |
| `DTS.Common.Events` | `CalibrationBehaviorSettingChangedEvent`, `CalibrationBehaviorSettableInViewerChangedEvent`, `ViewerSettingsVisibilityChangedEvent` |
| `DTS.Common.Interactivity` | `InteractionRequest<T>`, `Notification`, `Confirmation` |
| `DTS.Common.Interface` | `IViewerSettingsViewModel`, `IBaseViewModel`, `IViewerSettingsView` |
| `Prism.Events` | `IEventAggregator` |
| `Prism.Regions` | `IRegionManager` |
| `Unity` | `IUnityContainer` |
| `System.Windows` | `Visibility` |
| `DTS.Viewer.ViewerSettings.Resources` | `StringResources` (localized display strings) |
### What Depends On This Module
Not determinable from source alone—depends on which modules reference `IViewerSettingsViewModel` or instantiate `ViewerSettingsViewModel`.
---
## 5. Gotchas
1. **`new` Keyword Hiding**: Multiple members (`PropertyChanged`, `OnPropertyChanged`, `IsBusy`, `IsDirty`, `IsNavigationIncluded`, `ConfirmationRequest`) use the `new` keyword to hide base class members. This breaks polymorphism—if the object is cast to the base type, the base members will be used instead of these overrides.
2. **Copy-Paste Error in XML Comment**: The constructor's XML documentation references `"TestSummaryViewListModel"`—incorrect for this class.
3. **Empty `PublishChanges()` Method**: The method has no implementation. Its intended purpose is unclear from source alone.
4. **Non-Standard Naming Convention**: The private lock object `MyLock` uses PascalCase rather than the conventional underscore-prefix or camelCase pattern used elsewhere in the class.
5. **Visibility Property Name Convention**: The `OnPropertyChanged` method contains special logic that triggers on any property name ending with `"Visibility"` (except `"OverallSettingsVisibility"`). Adding new visibility properties will have this side effect automatically.
6. **CalibrationBehaviorSetting Getter Linear Search**: The getter iterates through `AvailableCalibrationBehaviors` on every access to find the matching `DisplayedCalibrationBehavior`. This is O(n) for each get operation.

View File

@@ -0,0 +1,242 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReport/PSDReportModule.cs
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReport/PSDReportSession.cs
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReport/Bootstrapper.cs
generated_at: "2026-04-16T10:59:56.665208+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "24a83d36ea7d74c2"
---
# PSDReport Module Documentation
## 1. Purpose
The `DTS.Viewer.PSDReport` module is a Prism-based plugin module for the DTS Viewer application that provides PSD (Power Spectral Density) report functionality. It implements the `IModule` interface for modular composition and can operate in both standalone and integrated modes. The module includes custom assembly attributes for metadata discovery, a session management system for bootstrapping Prism infrastructure, and a custom `UnityBootstrapper` for configuring dependency injection, region adapters, and dynamic module loading.
---
## 2. Public Interface
### PSDReportModule.cs
**Class: `PSDReportModule`**
```csharp
public PSDReportModule(IUnityContainer unityContainer)
```
Constructor accepting an `IUnityContainer` dependency injection.
```csharp
public void Initialize()
```
Registers `IPSDReportModule` to `PSDReportModule` with `ContainerControlledLifetimeManager` (singleton lifetime).
```csharp
public void StartSession()
```
Resolves `IEventAggregator`, publishes a `LoadViewModulEvent` with `LoadViewModulArg`, and sets `SessionStarted` to `true`.
```csharp
public void RegisterTypes(IContainerRegistry containerRegistry)
```
Prism module lifecycle method; calls `Initialize()`.
```csharp
public void OnInitialized(IContainerProvider containerProvider)
```
Prism module lifecycle method; currently empty implementation.
**Property: `SessionStarted`** (read-only)
```csharp
public bool SessionStarted { get; private set; }
```
Indicates whether `StartSession()` has been called.
---
**Class: `PSDReportModuleNameAttribute`** (extends `TextAttribute`)
```csharp
public PSDReportModuleNameAttribute()
public PSDReportModuleNameAttribute(string s)
```
Assembly-level attribute returning `AssemblyNames.PSDReport.ToString()` for `AssemblyName`.
```csharp
public override Type GetAttributeType()
public override string GetAssemblyName()
```
---
**Class: `PSDReportModuleImageAttribute`** (extends `ImageAttribute`)
```csharp
public PSDReportModuleImageAttribute()
public PSDReportModuleImageAttribute(string s)
```
Assembly-level attribute providing image, name, group, and region metadata.
```csharp
public override BitmapImage AssemblyImage { get; }
public override string AssemblyName { get; }
public override string AssemblyGroup { get; } // Returns eAssemblyGroups.Viewer.ToString()
public override eAssemblyRegion AssemblyRegion { get; } // Returns eAssemblyRegion.PSDReportRegion
```
---
### PSDReportSession.cs
**Class: `PSDReportSession`**
```csharp
public PSDReportSession()
```
Default (empty) constructor.
```csharp
public void CreateSession(bool standalone, string customConfigPath = "")
```
Creates the bootstrapper, resolves container services (`IUnityContainer`, `IEventAggregator`, `IServiceLocator`, `IRegionManager`), loads plugins via `PluginManager`, and publishes the plugin list via `AssemblyListNotificationViewer` event.
```csharp
public void Terminate()
```
Empty implementation; intended for shutdown scenarios.
**Properties:**
```csharp
public IUnityContainer Container { get; private set; }
public IServiceLocator _serviceLocator { get; private set; }
public IEventAggregator _eventAggregator { get; private set; }
public IRegionManager _regionManager { get; private set; }
public string CustomConfigPath { get; set; }
```
---
### Bootstrapper.cs
**Class: `Bootstrapper`** (extends `UnityBootstrapper`)
```csharp
public Bootstrapper(bool standalone, string customConfigPath = "")
```
Constructor accepting standalone mode flag and optional custom config path.
```csharp
protected override void ConfigureContainer()
```
Registers `IPSDReportMainViewGrid` to `PSDReportMainViewGrid` and `IPSDReportMainViewModel` to `PSDReportMainViewModel` (singleton). Calls `base.ConfigureContainer()`.
```csharp
protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
```
Registers region adapters for `Selector`, `ItemsControl`, `ContentControl`, and conditionally `StackPanel` (standalone mode only). Each registration is wrapped in try/catch to handle duplicate mappings.
```csharp
protected override DependencyObject CreateShell()
```
Creates the shell by resolving `IPSDReportMainViewModel`, registering regions dynamically, setting DataContext, and initializing the view model. Returns `null` on exception.
```csharp
protected override IModuleCatalog CreateModuleCatalog()
```
Returns resolved `IModuleCatalog` or creates new `AggregateModuleCatalog`.
```csharp
protected override void ConfigureModuleCatalog()
```
For standalone mode only: reads plugin folder paths from configuration section `DTS.Common.Core.PluginLib.Config` and creates a `DirectoryModuleCatalog`.
```csharp
protected override void InitializeModules()
```
For standalone mode only: registers `IDTSViewRegionManager` to `DTSViewRegionManager` (singleton) and calls `base.InitializeModules()`.
**Properties:**
```csharp
public bool Standalone { get; set; }
public string CustomConfigPath { get; set; }
public IServiceLocator _ServiceLocator { get; private set; }
public IEventAggregator _EventAggregator { get; private set; }
```
---
## 3. Invariants
1. **Singleton Registration**: `IPSDReportModule` is registered with `ContainerControlledLifetimeManager`, ensuring a single instance per container.
2. **Session State**: `SessionStarted` is `false` until `StartSession()` is called; it cannot be reset to `false` through the public interface.
3. **Bootstrapper Creation**: `CreateBootstrapper()` will not create a new bootstrapper if `_bootstrapper` is already non-null.
4. **Standalone Mode Behavior**:
- `ConfigureModuleCatalog()` only adds directory catalog when `Standalone` is `true`.
- `InitializeModules()` only registers `IDTSViewRegionManager` when `Standalone` is `true`.
- `StackPanel` region adapter is only registered when `Standalone` is `true`.
5. **Region Registration**: In `CreateShell()`, regions are only added if they don't already exist (`ContainsRegionWithName` check).
6. **Assembly Attributes**: Both `PSDReportModuleNameAttribute` and `PSDReportModuleImageAttribute` are decorated with `AllowMultiple = false`.
---
## 4. Dependencies
### This module depends on:
**Prism Framework:**
- `Prism.Ioc` - `IContainerRegistry`, `IContainerProvider`
- `Prism.Modularity` - `IModule`, `ModuleAttribute`, `IModuleCatalog`
- `Prism.Events` - `IEventAggregator`
- `Microsoft.Practices.Prism.Events` - `IEventAggregator` (legacy)
- `Microsoft.Practices.Prism.Modularity` - `IModuleCatalog`, `UnityBootstrapper`
- `Microsoft.Practices.Prism.Regions` - `IRegionManager`, `RegionAdapterMappings`, `Region`, `RegionManager`
- `Microsoft.Practices.Prism.UnityExtensions` - `UnityBootstrapper`
**Unity DI:**
- `Unity` - `IUnityContainer`
- `Unity.Lifetime` - `ContainerControlledLifetimeManager`
- `Microsoft.Practices.Unity` - `IUnityContainer`, `InjectionMember`
**DTS Common Libraries:**
- `DTS.Common` - `AssemblyNames`, `AssemblyInfo`, `eAssemblyGroups`, `eAssemblyRegion`
- `DTS.Common.Events` - `LoadViewModulEvent`, `LoadViewModulArg`, `AssemblyListNotificationViewer`, `AssemblyListInfo`
- `DTS.Common.Interface` - `IPSDReportModule`, `IPSDReportMainViewGrid`, `IPSDReportMainViewModel`, `IShellViewModel`, `IDTSViewRegionManager`
- `DTS.Common.Base` - `TextAttribute`, `ImageAttribute`
- `DTS.Common.Core.PluginLib` - `PluginManager`, `PluginConfigSectionHandler`, `FilterHashElement`, `DTSViewRegionManager`
**WPF/.NET:**
- `System.Windows` - `DependencyObject`, `DependencyProperty`
- `System.Windows.Controls` - `ItemsControl`, `ContentControl`, `StackPanel`
- `System.Windows.Media.Imaging` - `BitmapImage`
- `System.Configuration` - `ConfigurationManager`
- `System.ComponentModel.Composition.Hosting` - (imported but not directly used in visible code)
### What depends on this module:
Not determinable from source alone. The module publishes `LoadViewModulEvent` and `AssemblyListNotificationViewer` events, suggesting other components subscribe to these events.
---
## 5. Gotchas
1. **Dual EventAggregator Imports**: The code imports `IEventAggregator` from both `Prism.Events` (modern) and `Microsoft.Practices.Prism.Events` (legacy). `PSDReportModule` uses the modern namespace while `PSDReportSession` uses the legacy namespace. This could cause runtime issues if they resolve to different instances.
2. **Empty Constructor Comment**: `PSDReportSession` has a comment `// ReSharper disable EmptyConstructor` suggesting the empty constructor may be intentional but non-obvious.
3. **Bootstrapper Memory Footprint**: The comment in `PSDReportSession` notes: *"It appears that the current bootstrapper loads around 40 MB into memory. To completely unload the bootstrapper would take same research and effort."* There is no mechanism to unload or recreate the bootstrapper.
4. **Silent Failure in CreateShell**: `CreateShell()` catches all exceptions, stores the message in a local variable `s` that is never used, and returns `null`. This silently swallows errors.
5. **Region Adapter Registration Swallows Errors**: `ConfigureRegionAdapterMappings()` wraps each registration in try/catch with empty catch blocks, silently ignoring duplicate mapping exceptions.
6. **Commented-Out Code in ConfigureContainer**: There is commented-out code for conditional registration based on `Standalone` mode, suggesting the registration strategy changed but the old code was preserved.
7. **TODO Comment**: `PSDReportSession.CreateSession()` contains `//TODO: review publishPlugins vs base.InitializeModules();` indicating incomplete design review.
8. **Inconsistent Naming Convention**: Some private fields use underscore prefix (`_unityContainer`, `_eventAggregator`) while others don't (`Container`). Public properties mix conventions (`_serviceLocator` is public with underscore prefix).
9. **Unused Imports**: `System.Runtime.InteropServices.ComTypes` is imported in `Bootstrapper.cs` but the `IStream` type is not used.
10. **Module Self-Registration**: `PSDReportModule.Initialize()` registers its own type (`IPSDReportModule``PSDReportModule`), which is unusual since the module instance already exists when `Initialize()` is called.

View File

@@ -0,0 +1,41 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReport/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T11:03:45.800273+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "d475bf20384ac0ba"
---
# Documentation: DTS.Viewer.PSDReport Assembly Configuration
## 1. Purpose
This source file defines the assembly metadata and versioning information for the `DTS.Viewer.PSDReport` library. As a standard .NET `AssemblyInfo.cs` file, it configures the manifest embedded within the compiled DLL, specifying the assembly title, version, copyright, and COM visibility settings. It serves as the build configuration entry point for this specific reporting module within the larger DTS Viewer application.
## 2. Public Interface
This file does not contain executable classes or methods. It applies assembly-level attributes that affect the compiled output's metadata.
* **`AssemblyTitle("DTS.Viewer.PSDReport")`**: Sets the friendly name for the assembly.
* **`AssemblyProduct("DTS.Viewer.PSDReport")`**: Specifies the product name associated with the assembly.
* **`AssemblyCopyright("Copyright © 2021")`**: Defines the copyright information.
* **`ComVisible(false)`**: Indicates that types within this assembly are not visible to COM components.
* **`Guid("3d57ca12-a637-4cdb-b673-d9a5ff0cf062")`**: Specifies a unique identifier for the assembly, used if the project is exposed to COM.
* **`AssemblyVersion("1.0.0.0")`**: Sets the assembly version number (Major.Minor.Build.Revision).
* **`AssemblyFileVersion("1.0.0.0")`**: Sets the file version number displayed in the file properties.
## 3. Invariants
* **COM Visibility:** All types within this assembly are explicitly hidden from COM components (`ComVisible(false)`).
* **Versioning:** The assembly version and file version are currently fixed at `1.0.0.0`. They are not configured to auto-increment (the wildcard syntax `1.0.*` is commented out).
* **Identity:** The `Guid` `3d57ca12-a637-4cdb-b673-d9a5ff0cf062` uniquely identifies this specific assembly globally.
## 4. Dependencies
* **Internal Dependencies:**
* `System.Reflection`: Required for the assembly attribute definitions.
* `System.Runtime.CompilerServices`: Included by default in the template; not actively used for `InternalsVisibleTo` in this snippet.
* `System.Runtime.InteropServices`: Required for the `ComVisible` and `Guid` attributes.
* **External Dependencies:** None identified in this file. The project likely references other DTS modules, but those relationships are defined in the project file (`.csproj`), not here.
## 5. Gotchas
* **Static Versioning:** The version is hardcoded to `1.0.0.0`. If the build process does not externally override these values (e.g., via CI/CD pipeline parameters), all builds will report as version 1.0.0.0, making version tracking difficult.
* **Empty Metadata:** The `AssemblyDescription`, `AssemblyConfiguration`, `AssemblyCompany`, and `AssemblyTrademark` fields are empty strings. This may trigger default behavior or result in missing metadata in the compiled DLL properties.
* **Legacy Format:** The existence of an explicit `AssemblyInfo.cs` suggests this project may be using the older .NET Framework SDK style project format. Newer SDK-style projects typically auto-generate this information, which can lead to conflicts (CS0579) if the project file is later upgraded without removing this file.

View File

@@ -0,0 +1,72 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReport/Resources/TranslateExtension.cs
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReport/Resources/StringResources.Designer.cs
generated_at: "2026-04-16T11:03:12.267125+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "01cf0d845cbc5765"
---
# Documentation: DTS.Viewer.PSDReport.Resources
## 1. Purpose
This module provides localization infrastructure for the `DTS.Viewer.PSDReport` namespace. It consists of a strongly-typed resource accessor class (`StringResources`) generated from a `.resx` file, and a WPF XAML markup extension (`TranslateExtension`) that allows UI elements to bind directly to localized strings using a key. The module ensures that the report module can present user-facing text in different languages without hardcoding strings in the UI logic.
## 2. Public Interface
### Class: `TranslateExtension`
**Namespace:** `DTS.Viewer.PSDReport`
**Inheritance:** `System.Windows.Markup.MarkupExtension`
This class allows XAML bindings to retrieve localized strings declaratively.
* **Constructor: `TranslateExtension(string key)`**
* Initializes the extension with the resource key to be looked up.
* **Method: `ProvideValue(IServiceProvider serviceProvider)`**
* **Return Type:** `object` (attributed to return `string`)
* **Behavior:** Looks up the provided `_key` via `StringResources.ResourceManager`. Returns the localized string if found. If the key is null or empty, it returns the constant `"#stringnotfound#"`. If the lookup fails (returns null), it returns `"#stringnotfound# "` appended with the missing key name.
### Class: `StringResources`
**Namespace:** `DTS.Viewer.PSDReport.Resources`
**Accessibility:** `internal`
This is a strongly-typed, auto-generated resource class for looking up culture-specific strings.
* **Property: `ResourceManager`** (static, `System.Resources.ResourceManager`)
* Returns the cached `ResourceManager` instance for this assembly. It is lazily initialized upon first access.
* **Property: `Culture`** (static, `System.Globalization.CultureInfo`)
* Gets or sets the current UI culture used for resource lookups. This overrides the current thread's `CurrentUICulture` for resource lookups via this class.
* **Resource Accessors** (static, `string`)
* The following properties return localized strings corresponding to their keys:
* `DataHeader` ("Data")
* `DataSelectionHeader` ("Data selection")
* `GraphsDefaultTitle` ("Graphs ")
* `ModificationsHeader` ("Modify")
* `PSDHeader` ("PSD")
* `PSDResultsHeader` ("Results")
* `PSDSettingsHeader` ("PSD Settings")
* `SettingsTitle` ("Settings")
* `TestsDefaultTitle` ("Tests ")
## 3. Invariants
* **Fallback Behavior:** `TranslateExtension.ProvideValue` will never return `null`. It guarantees a string return, defaulting to the literal `"#stringnotfound#"` (with optional key suffix) for missing or invalid keys.
* **Auto-generation:** `StringResources` is auto-generated. Manual modifications to `StringResources.Designer.cs` will be lost upon regeneration. The source of truth is the corresponding `.resx` file.
* **Internal Visibility:** `StringResources` is marked `internal`, restricting access to within the `DTS.Viewer.PSDReport` assembly.
* **Thread Safety:** The `ResourceManager` property in `StringResources` uses a standard lazy initialization check (`object.ReferenceEquals(resourceMan, null)`). While standard for generated code, it is not strictly thread-safe in a race condition scenario (though usually harmless for resource managers).
## 4. Dependencies
* **Internal Dependencies:**
* `TranslateExtension` depends on `StringResources` (specifically `StringResources.ResourceManager`) to perform lookups.
* **External Framework Dependencies:**
* `System.Windows.Markup`: Required for `MarkupExtension` and `MarkupExtensionReturnTypeAttribute` (implies a dependency on WPF/WindowsBase).
* `System.Resources`: Required for `ResourceManager`.
* `System.Globalization`: Required for `CultureInfo`.
## 5. Gotchas
* **Dynamic vs. Strongly-typed Access:** `TranslateExtension` uses `ResourceManager.GetString` (dynamic lookup by string) rather than the strongly-typed properties (e.g., `StringResources.DataHeader`). This means typos in XAML keys will not cause compile-time errors but will result in the `"#stringnotfound#"` fallback string appearing in the UI at runtime.
* **Missing Source File:** The actual translation values (key-value pairs) reside in a `.resx` file (e.g., `StringResources.resx`) which is not included in the provided source. The default English values shown in the XML comments (e.g., "Data", "Graphs ") are the only insight into the actual content.
* **Trailing Spaces:** The default values for `GraphsDefaultTitle` ("Graphs ") and `TestsDefaultTitle` ("Tests ") appear to contain trailing spaces in the auto-generated comments. It is unclear if this is intentional or a data artifact without seeing the `.resx` file.

View File

@@ -0,0 +1,83 @@
---
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<IEventAggregator>()` 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.

View File

@@ -0,0 +1,102 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReport/ViewModel/PSDReportMainViewModel.cs
generated_at: "2026-04-16T11:03:20.289994+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "280cd655454826b4"
---
# Documentation: PSDReportMainViewModel
## 1. Purpose
The `PSDReportMainViewModel` class serves as the primary view model for the PSD Report module within the DTS Viewer application. It acts as a central coordinator, managing the lifecycle and composition of various child views (graphs, tests, settings, navigation) via Prism's RegionManager and Unity dependency injection. This module handles user interactions related to data selection, calibration settings, and channel view modes, while maintaining state for loaded and selected tests/graphs and communicating changes to other components via an `IEventAggregator`.
## 2. Public Interface
### Constructor
* `PSDReportMainViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)`
* Initializes the view model, creates interaction requests (`NotificationRequest`, `ConfirmationRequest`), resolves the main view (`IPSDReportMainViewGrid`), and sets the DataContext.
### Properties
* `IBaseView View { get; set; }`: Gets or sets the associated view instance.
* `InteractionRequest<Notification> NotificationRequest { get; }`: Request object for triggering notifications.
* `InteractionRequest<Confirmation> ConfirmationRequest { get; }`: Request object for triggering confirmation dialogs.
* **Region Context Properties**:
* `object ContextNavigationRegion`: Content for the Navigation region.
* `object ContextGraphsRegion`: Content for the GraphList region. **Note:** Getter/Setter references `GraphListRegion`.
* `object ContextGraphListRegion`: Content for the GraphList region. **Note:** Identical to `ContextGraphsRegion`.
* `object ContextTestsRegion`: Content for the Tests region.
* `object ContextLegendRegion`: Content for the Legend region.
* `object ContextPropertyRegion`: Auto-property; does not appear to interact with the View.
* `object ContextChartOptionsRegion`: Content for the ChartOptions region.
* `object ContextViewerSettingsRegion`: Content for the Settings region.
* `object ContextReportDataSelectRegion`: Content for the DataSelect region.
* `object ContextGraphRegion`: Content for the Graph region.
* `object ContextReportChartOptionsRegion`: Content for the ReportChartOptions region.
* `object ContextReportResultsRegion`: Content for the ReportResults region.
* `string ConfigPath { get; set; }`: Throws `NotImplementedException`.
* `string TitleTests { get; set; }`: Title for the Tests section, updated based on selection counts.
* `int TotalSelectedTests { get; set; }`: Count of selected tests; updates `TitleTests`.
* `int TotalLoadedTests { get; set; }`: Count of loaded tests; updates `TitleTests`.
* `string TitleGraphs { get; set; }`: Title for the Graphs section.
* `int TotalSelectedGraphs { get; set; }`: Count of selected graphs.
* `int TotalLoadedGraphs { get; set; }`: Count of loaded graphs.
* `string SelectedDataFolder { get; set; }`: Sets the data folder and publishes `DataFolderChangedEvent`. Ignores null/empty values.
* `string SelectedDataFile { get; set; }`: Sets the data file and publishes `DataFolderChangedEvent`. Ignores null/empty values.
* `IsoViewMode ChannelCodeViewMode { get; set; }`: Gets or sets the channel view mode; publishes `ChannelCodesViewChangedEvent`.
* `CalibrationBehaviors CalibrationBehaviorSetting { get; set; }`: Gets or sets calibration behavior; publishes `CalibrationBehaviorSettingChangedEvent`.
* `bool CalibrationBehaviorSettableInViewer { get; set; }`: Determines if calibration is settable; publishes `CalibrationBehaviorSettableInViewerChangedEvent` and manipulates View tab selection directly.
* `Visibility SettingsVisibility { get; }`: Controls visibility of settings.
* `bool IsBusy { get; set; }`: Controls busy indicator visibility.
* `string IsBusyMessage { get; set; }`: Text displayed when busy.
* `bool IsMenuIncluded { get; set; }`: Flag for menu inclusion.
* `bool IsNavigationIncluded { get; set; }`: Flag for navigation inclusion.
* `bool IsDirty`: Throws `NotImplementedException`.
### Methods
* `List<FrameworkElement> GetRegions()`: Retrieves child elements named "Region" from the `MainShell`.
* `void Initialize()`: Calls `Subscribe()` to register event listeners.
* `void Initialize(object parameter)`: Sets the `Parent` window model, updates parent properties, and subscribes to events.
* `void LeftKeyPress()`: Throws `NotImplementedException`.
* `void RightKeyPress()`: Throws `NotImplementedException`.
* `void ZoomReset()`: Publishes `ResetZoomChangedEvent`.
* `void SelectAndIncludeDataFile(string value)`: Sets the selected file and publishes a `DataFolderChangedEvent` with `SetSelected` flag.
* `event PropertyChangedEventHandler PropertyChanged`: Event for property change notifications (hides base event).
## 3. Invariants
* **View Resolution**: The `View` property is expected to be an instance of `PSDReportMainViewGrid` (resolved via `IPSDReportMainViewGrid`). All region properties cast `View` to this concrete type, implying the interface `IPSDReportMainViewGrid` is not used for region access, or the concrete type is strictly required for UI element access.
* **Event Aggregator**: The class relies heavily on `_eventAggregator` being non-null for almost all property setters and initialization logic.
* **Parent Type**: In `Initialize(object parameter)`, the `parameter` must be castable to `IBaseWindowModel`.
* **Busy Counter**: The private `reads` integer is used to track nested "busy" states during graph channel reading; it assumes a balanced start/stop notification pattern.
## 4. Dependencies
### External Dependencies (Inferred from usings)
* **Prism**: `IEventAggregator`, `IRegionManager`, `InteractionRequest`, `Notification`, `Confirmation`.
* **Unity**: `IUnityContainer`.
* **System.Windows**: `FrameworkElement`, `Visibility`.
### Internal Dependencies (DTS Namespace)
* **Common**: `BaseViewModel`, `IBaseView`, `IBaseWindowModel`, `IBaseViewModel`, `Utils`.
* **Enums**: `IsoViewMode`, `CalibrationBehaviors`.
* **Events**: `DataFolderChangedEvent`, `ChannelCodesViewChangedEvent`, `CalibrationBehaviorSettingChangedEvent`, `LoadViewModulEvent`, `TestLoadedCountNotification`, etc.
* **Views/ViewModels (Resolved via Unity)**:
* `IPSDReportMainViewGrid`
* `INavigationView` / `INavigationViewModel`
* `IPSDReportResultsView` / `IPSDReportResultsViewModel`
* `IPSDReportSettingsView` / `IPSDReportSettingsViewModel`
* `IChartOptionsView` / `IChartOptionsViewModel`
* `IGraphView` / `IGraphViewModel`
* `IGraphMainView` / `IGraphMainViewModel`
* `IViewerSettingsView` / `IViewerSettingsViewModel`
* `ITestSummaryListView` / `ITestSummaryListViewModel`
## 5. Gotchas
* **Not Implemented Members**: Several members throw `NotImplementedException` (`ConfigPath`, `IsDirty`, `LeftKeyPress`, `RightKeyPress`). These are likely interface requirements that have not been fulfilled.
* **Duplicate Region Properties**: `ContextGraphsRegion` and `ContextGraphListRegion` are functionally identical; both access `((PSDReportMainViewGrid)View).GraphListRegion.Content`. This may be a copy-paste error or redundant API surface.
* **MVVM Violation (View Coupling)**: The `CalibrationBehaviorSettableInViewer` setter directly manipulates View UI elements (`graphsTab`, `testsTab`, `chartResultsTab`) by casting `View` to `PSDReportMainViewGrid`. This breaks the separation of concerns typically enforced in MVVM and creates a hard dependency on the concrete View type.
* **Member Hiding**: The `new` keyword is used to hide inherited members (`IsBusy`, `IsBusyMessage`, `IsMenuIncluded`, `IsNavigationIncluded`, `PropertyChanged`, `OnPropertyChanged`). This suggests a mismatch between the base class implementation and the requirements of this specific view model, which could lead to confusion if the object is referenced via a base type pointer.
* **Unused Property**: `ContextPropertyRegion` is defined as an auto-property but is never assigned or used within the class logic, unlike other region properties.
* **Magic Strings**: Region names (e.g., "Graph", "DataSelect") and property names in `OnPropertyChanged` are passed as string literals.

View File

@@ -0,0 +1,96 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReportResults/PSDReportResultsModule.cs
generated_at: "2026-04-16T10:59:25.221294+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "1cb458d29a5aed08"
---
# Documentation: PSDReportResultsModule
## 1. Purpose
This module serves as the entry point for the "PSD Report Results" component within the DTS Viewer application. It is a Prism Module (`PSDReportResultsModule`) responsible for registering its associated View and ViewModel implementations with the Unity dependency injection container. Additionally, it defines assembly-level attributes to expose metadata (name, image, group, and region) to the broader application, likely for dynamic UI generation or navigation purposes.
## 2. Public Interface
### Class: `PSDReportResultsModule`
Implements `Prism.Modularity.IModule`.
* **`PSDReportResultsModule(IUnityContainer unityContainer)`**
* Constructor that accepts an `IUnityContainer` instance and stores it in a readonly field `_unityContainer`.
* **`void Initialize()`**
* Registers types with the Unity container.
* Maps `IPSDReportResultsViewModel` to `PSDReportResultsViewModel`.
* Maps `IPSDReportResultsView` to `PSDReportResultsView`.
* **`void OnInitialized(IContainerProvider containerProvider)`**
* Implementation of `IModule.OnInitialized`. Currently has an empty body (no logic executed).
* **`void RegisterTypes(IContainerRegistry containerRegistry)`**
* Implementation of `IModule.RegisterTypes`. Invokes the `Initialize()` method to perform dependency registration.
### Class: `PSDReportResultsModuleNameAttribute`
Inherits from `DTS.Common.Interface.TextAttribute`.
* **`PSDReportResultsModuleNameAttribute()`**
* Default constructor.
* **`PSDReportResultsModuleNameAttribute(string s)`**
* Constructor accepting a string argument `s` (which is unused in the body).
* **`override string AssemblyName { get; }`**
* Returns the string representation of `DTS.Common.AssemblyNames.PSDReportResults`.
* **`override Type GetAttributeType()`**
* Returns `typeof(TextAttribute)`.
* **`override string GetAssemblyName()`**
* Returns the `AssemblyName` property value.
### Class: `PSDReportResultsModuleImageAttribute`
Inherits from `DTS.Common.Interface.ImageAttribute`.
* **`PSDReportResultsModuleImageAttribute()`**
* Default constructor.
* **`PSDReportResultsModuleImageAttribute(string s)`**
* Constructor accepting a string argument `s`. Initializes the private `_img` field via `AssemblyInfo.GetImage`.
* **`override BitmapImage AssemblyImage { get; }`**
* Getter initializes (if null) and returns a `BitmapImage` retrieved via `AssemblyInfo.GetImage`.
* **`override string AssemblyName { get; }`**
* Returns the string representation of `DTS.Common.AssemblyNames.PSDReportResults`.
* **`override string AssemblyGroup { get; }`**
* Returns the string representation of `DTS.Common.eAssemblyGroups.Viewer`.
* **`override eAssemblyRegion AssemblyRegion { get; }`**
* Returns `DTS.Common.eAssemblyRegion.PSDReportResultsRegion`.
* **`override Type GetAttributeType()`**
* Returns `typeof(ImageAttribute)`.
* **`override BitmapImage GetAssemblyImage()`**
* Returns the `AssemblyImage` property.
* **`override string GetAssemblyName()`**
* Returns the `AssemblyName` property.
* **`override string GetAssemblyGroup()`**
* Returns the `AssemblyGroup` property.
* **`override eAssemblyRegion GetAssemblyRegion()`**
* Returns the `AssemblyRegion` property.
## 3. Invariants
* **Module Name:** The Prism module name is fixed as `"PSDReportResults"` via the `[Module]` attribute.
* **Assembly Group:** The module always identifies itself as part of the `Viewer` group via `eAssemblyGroups.Viewer`.
* **Assembly Region:** The module is always associated with `eAssemblyRegion.PSDReportResultsRegion`.
* **Type Registration:** The `IPSDReportResultsView` and `IPSDReportResultsViewModel` interfaces are strictly mapped to their concrete implementations `PSDReportResultsView` and `PSDReportResultsViewModel` respectively.
## 4. Dependencies
**Internal Dependencies (referenced types):**
* `DTS.Common`: Uses `AssemblyNames` enum.
* `DTS.Common.Interface`: Uses `TextAttribute`, `ImageAttribute`, `AssemblyInfo`, `eAssemblyGroups`, and `eAssemblyRegion`.
* `DTS.Viewer.PSDReportResults`: Contains the concrete `PSDReportResultsView` and `PSDReportResultsViewModel` (inferred from registration calls, though the namespace matches the file).
**External Frameworks:**
* `Prism.Ioc`: Uses `IContainerProvider`.
* `Prism.Modularity`: Uses `IModule`, `ModuleAttribute`.
* `Unity`: Uses `IUnityContainer`.
* `System.Windows.Media.Imaging`: Uses `BitmapImage`.
## 5. Gotchas
* **Redundant Initialization Logic:** The `RegisterTypes` method calls `Initialize()`. This is unusual; typically, `RegisterTypes` uses the passed `IContainerRegistry` argument for registration, while `Initialize` uses the injected `IUnityContainer`. Here, the module ignores the `IContainerRegistry` argument and relies on the injected `_unityContainer` inside `Initialize`. This mixes Prism's modular initialization lifecycle with direct Unity container usage.
* **Unused Constructor Parameters:** Both attribute classes (`PSDReportResultsModuleNameAttribute` and `PSDReportResultsModuleImageAttribute`) have constructors accepting a `string s` parameter. In both cases, this parameter is completely ignored in the implementation.
* **Property Side Effects:** The getter for `PSDReportResultsModuleImageAttribute.AssemblyImage` has a side effect: it assigns a value to the private `_img` field if accessed. While the constructor also attempts to set this, the property getter logic `_img = ...; return _img;` will re-fetch the image every time if `_img` is null, or overwrite it if called repeatedly (though the logic implies it just returns it after assignment).
* **Empty Lifecycle Hook:** `OnInitialized` is explicitly empty. If initialization logic were required to run after container registration, it would need to be added here, but currently, it does nothing.

View File

@@ -0,0 +1,50 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReportResults/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T11:02:08.508418+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "a578e8bbaedafe8e"
---
# Documentation: DTS.Viewer.PSDReportResults Assembly Configuration
## 1. Purpose
This source file provides assembly-level metadata and configuration attributes for the `DTS.Viewer.PSDReportResults` library. It defines the assembly's identity, version information, and COM visibility settings within the larger "DTS Viewer" application ecosystem. It exists to embed standard .NET assembly information into the compiled DLL.
## 2. Public Interface
This file does not contain public classes, methods, or functions. It strictly defines assembly-level attributes using C# attribute syntax.
**Defined Attributes:**
* **`AssemblyTitle`**: Set to `"DTS.Viewer.PSDReportResults"`.
* **`AssemblyDescription`**: Set to an empty string.
* **`AssemblyConfiguration`**: Set to an empty string.
* **`AssemblyCompany`**: Set to an empty string.
* **`AssemblyProduct`**: Set to `"DTS.Viewer.PSDReportResults"`.
* **`AssemblyCopyright`**: Set to `"Copyright © 2022"`.
* **`AssemblyTrademark`**: Set to an empty string.
* **`AssemblyCulture`**: Set to an empty string.
* **`ComVisible`**: Set to `false`. Prevents types in this assembly from being visible to COM components.
* **`Guid`**: Set to `"486af003-0dec-4b05-a7a5-39e6ca9ec629"`. Acts as the ID for the type library if the project is exposed to COM.
* **`AssemblyVersion`**: Set to `"1.0.0.0"`.
* **`AssemblyFileVersion`**: Set to `"1.0.0.0"`.
## 3. Invariants
* **COM Visibility:** The `ComVisible(false)` attribute ensures that all types within this assembly are not exposed to COM by default. To expose a specific type, that type must be explicitly marked with `ComVisible(true)`.
* **Versioning:** Both the assembly version and file version are currently fixed at `1.0.0.0`.
* **Identity:** The `Guid` attribute provides a unique identifier for this specific assembly, which remains constant regardless of version changes.
## 4. Dependencies
**Internal Dependencies (Imports):**
* `System.Reflection`: Required for the assembly attribute classes (e.g., `AssemblyTitleAttribute`, `AssemblyVersionAttribute`).
* `System.Runtime.CompilerServices`: Imported by default in standard AssemblyInfo templates, though no specific attributes from this namespace are used in this file.
* `System.Runtime.InteropServices`: Required for the `ComVisible` and `Guid` attributes.
**External Dependencies:**
* None identified from this source file alone. The specific runtime or logic dependencies of the `DTS.Viewer.PSDReportResults` assembly are not defined here.
## 5. Gotchas
* **Missing Metadata:** The `AssemblyDescription`, `AssemblyConfiguration`, and `AssemblyCompany` attributes are explicitly set to empty strings. This may result in missing metadata in the compiled DLL properties, which can be problematic for internal tooling or inventory management.
* **Hardcoded Versions:** The `AssemblyVersion` and `AssemblyFileVersion` are hardcoded to `"1.0.0.0"`. If the project uses Continuous Integration (CI) for automatic versioning, this file may need to be ignored or modified during the build process; otherwise, every build will report as version 1.0.0.0.
* **Legacy Structure:** The presence of an explicit `AssemblyInfo.cs` suggests this project may be using the older .NET Framework SDK style project format. Newer SDK-style projects typically auto-generate this information in the `.csproj` file, though this file can still be used if the project is configured to not auto-generate assembly info.

View File

@@ -0,0 +1,92 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReportResults/Resources/TranslateExtension.cs
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReportResults/Resources/StringResources.Designer.cs
generated_at: "2026-04-16T11:02:06.405832+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "154eee0c947eb6d0"
---
# Documentation: DTS.Viewer.PSDReportResults.Resources
## 1. Purpose
This module provides localization infrastructure for the PSD Report Results viewer component. It consists of a strongly-typed resource accessor class (`StringResources`) generated from a `.resx` file, and a XAML markup extension (`TranslateExtension`) that allows UI elements to bind directly to localized strings declaratively within XAML markup.
## 2. Public Interface
### `TranslateExtension`
**Location:** `DTS.Viewer.PSDReportResults.Resources.TranslateExtension`
**Inheritance:** `System.Windows.Markup.MarkupExtension`
A XAML markup extension used to resolve localized strings at runtime.
* **Constructor**
```csharp
public TranslateExtension(string key)
```
Initializes the extension with the resource key to be looked up. The key is stored in a private readonly field `_key`.
* **Method: ProvideValue**
```csharp
public override object ProvideValue(IServiceProvider serviceProvider)
```
Resolves the localized string for the key provided in the constructor.
* Returns `NotFound` ("#stringnotfound#") if the `_key` is null or empty.
* Retrieves the string using `StringResources.ResourceManager.GetString(_key)`.
* Returns `NotFound + " " + _key` if the resource lookup returns null (key not found in resources).
### `StringResources`
**Location:** `DTS.Viewer.PSDReportResults.Resources.StringResources`
**Visibility:** `internal`
A strongly-typed resource class auto-generated by Visual Studio/ResGen. It provides access to localized strings defined in the associated `.resx` file.
* **Property: ResourceManager**
```csharp
internal static global::System.Resources.ResourceManager ResourceManager { get; }
```
Returns the cached `ResourceManager` instance for this assembly. It looks up resources named `"DTS.Viewer.PSDReportResults.Resources.StringResources"`.
* **Property: Culture**
```csharp
internal static global::System.Globalization.CultureInfo Culture { get; set; }
```
Gets or sets the current `CultureInfo` for resource lookups. Overrides the current thread's `CurrentUICulture` for this specific resource class.
* **Resource Properties (Static Strings)**
The following static properties return localized strings:
* `ChannelName` (Lookup key: "ChannelName")
* `ExportPSDHeader` (Lookup key: "ExportPSDHeader")
* `ExportPSDtoCSV` (Lookup key: "ExportPSDtoCSV")
* `ExportPSDtoPDF` (Lookup key: "ExportPSDtoPDF")
* `GRMS` (Lookup key: "GRMS")
* `PSDResultsHeader` (Lookup key: "PSDResultsHeader")
* `SampleRate` (Lookup key: "SampleRate")
## 3. Invariants
* **Auto-generation:** The `StringResources` class is auto-generated. Manual modifications to `StringResources.Designer.cs` will be lost upon regeneration. Changes must be made to the underlying `.resx` file.
* **Return Types:** `TranslateExtension` is decorated with `[MarkupExtensionReturnType(typeof(string))]`, guaranteeing that `ProvideValue` returns a string (or the fallback error string).
* **Fallback Behavior:** `TranslateExtension` will never return `null`. It guarantees a string return, either the localized value or a specific error constant.
* **Visibility:** `StringResources` is `internal`, restricting access to the `DTS.Viewer.PSDReportResults` assembly.
## 4. Dependencies
* **Internal Dependencies:**
* `TranslateExtension` depends entirely on `StringResources.ResourceManager` to perform lookups.
* **External Dependencies (Framework):**
* `System`
* `System.Windows.Markup` (for `MarkupExtension` and `IServiceProvider`)
* `System.Resources` (for `ResourceManager`)
* `System.Globalization` (for `CultureInfo`)
* `System.CodeDom.Compiler` (Attributes on `StringResources`)
## 5. Gotchas
* **Error String Variations:** The `TranslateExtension` returns different error strings depending on the failure mode.
* If the input `_key` is null/empty, it returns exactly `"#stringnotfound#"`.
* If the lookup fails (key is valid but missing in resources), it returns `"#stringnotfound# " + _key` (note the space and the appended key).
* Developers parsing or validating these strings must account for this difference.
* **Designer File Edits:** As noted in the auto-generated header, editing `StringResources.Designer.cs` directly is unsafe. The specific resource strings listed (e.g., `ChannelName`, `GRMS`) are the only ones currently defined; adding new ones requires regenerating this file.
* **Culture Management:** `StringResources.Culture` is a static property. Setting it changes the culture for all subsequent lookups within this resource manager, potentially affecting threading behavior if not managed carefully.

View File

@@ -0,0 +1,90 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReportResults/View/PSDReportResultsView.xaml.cs
generated_at: "2026-04-16T11:02:24.723243+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "7dcd71bef7b7c279"
---
# Documentation: PSDReportResultsView
## 1. Purpose
`PSDReportResultsView` is a WPF view component responsible for displaying PSD (likely Power Spectral Density) report results in the DTS Viewer application. It serves as the code-behind for a XAML view and implements the `IPSDReportResultsView` interface, indicating it follows an interface-based architecture pattern—likely for MVP (Model-View-Presenter) or MVVM (Model-View-ViewModel) separation. This module exists to render report data and handle user interactions with the grid view, such as column header clicks and search functionality.
---
## 2. Public Interface
### Class: `PSDReportResultsView`
**Inheritance/Implementation:**
- Implements: `IPSDReportResultsView` (from `DTS.Common.Interface`)
**Constructor:**
```csharp
public PSDReportResultsView()
```
Initializes a new instance of the view and calls `InitializeComponent()` to load the associated XAML layout.
---
### Methods
#### `GridViewColumnHeader_OnClick`
```csharp
private void GridViewColumnHeader_OnClick(object sender, System.Windows.RoutedEventArgs e)
```
Event handler for column header click events in a GridView. Currently contains no implementation (empty body).
**Parameters:**
- `sender` - The object that raised the event
- `e` - `System.Windows.RoutedEventArgs` containing event data
---
#### `GridViewColumnHeaderSearchable_OnSearch`
```csharp
private void GridViewColumnHeaderSearchable_OnSearch(object sender, System.Windows.RoutedEventArgs e)
```
Event handler for search operations on searchable column headers. Currently contains no implementation (empty body).
**Parameters:**
- `sender` - The object that raised the event
- `e` - `System.Windows.RoutedEventArgs` containing event data
---
## 3. Invariants
- The class must implement `IPSDReportResultsView` interface contract (specific members not visible in this source).
- `InitializeComponent()` must be called in the constructor for the XAML-defined UI to be instantiated.
- Both event handlers are `private`, indicating they are wired to XAML events and not intended for external invocation.
---
## 4. Dependencies
### This module depends on:
- `DTS.Common.Interface` — specifically `IPSDReportResultsView` interface
- `System.Windows` (implied by `RoutedEventArgs` usage)
### What depends on this module:
- **Cannot be determined from source alone.** The `IPSDReportResultsView` interface suggests a presenter or controller component likely holds a reference to this view, but no consumers are visible in this file.
---
## 5. Gotchas
- **Empty event handlers:** Both `GridViewColumnHeader_OnClick` and `GridViewColumnHeaderSearchable_OnSearch` have empty implementations. This may indicate:
- Incomplete functionality (tech debt)
- Placeholder methods for future implementation
- Dead code that should be removed if unused in XAML
- **Interface contract unknown:** The specific members required by `IPSDReportResultsView` are not visible in this source. It is unclear whether the class fully satisfies the interface or if required members are defined elsewhere (e.g., in the XAML partial or another partial class file).
- **XAML file not provided:** The associated `PSDReportResultsView.xaml` file is not included, so the actual UI structure, data bindings, and event wirings cannot be verified.

View File

@@ -0,0 +1,85 @@
---
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<IChannelGRMSSummary>` | Collection of GRMS summary results displayed to the user. Cleared and repopulated on `PSDReportGRMSValuesUpdatedEvent`. |
| `NotificationRequest` | `InteractionRequest<Notification>` | Interaction request for showing notifications to the user. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | 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<IChannelGRMSSummary>` 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<T>`
- **DTS.Common.Events** — `PSDReportGRMSValuesUpdatedEvent`, `PSDReportGRMSValuesUpdatedEventArg`, `GraphSelectedChannelsNotification`, `GraphSelectedChannelsNotificationArg`, `SaveReportToPDFRequestedEvent`, `SaveReportToPDFRequestedEventArgs`, `SaveReportToCSVRequestedEvent`, `SaveReportToCSVRequestedEventArgs`
- **DTS.Common.Interactivity** — `InteractionRequest<T>`, `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<T>`
### 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<T>` 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.

View File

@@ -0,0 +1,76 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReportSettings/PSDReportSettingsModule.cs
generated_at: "2026-04-16T10:59:04.135002+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "272bb780c04413d3"
---
# Documentation: PSDReportSettingsModule
## 1. Purpose
This module serves as the entry point for the "PSD Report Settings" feature within the DTS Viewer application. It is a Prism Module (`PSDReportSettingsModule`) responsible for registering its associated View, ViewModel, and Model dependencies with the Unity dependency injection container. Additionally, it defines assembly-level attributes to expose metadata (name, image, grouping, and region) to the main application shell, allowing the module to be discovered and displayed in the UI as an available component.
## 2. Public Interface
### Classes
**`PSDReportSettingsModule`**
Inherits from: `IModule`
* `PSDReportSettingsModule(IUnityContainer unityContainer)`: Constructor that accepts a `IUnityContainer` instance and stores it in a readonly field.
* `void RegisterTypes(IContainerRegistry containerRegistry)`: Implements `IModule.RegisterTypes`. Executes the `Initialize()` method to register types with the container.
* `void OnInitialized(IContainerProvider containerProvider)`: Implements `IModule.OnInitialized`. Currently contains no implementation logic.
* `void Initialize()`: Registers the following interface-to-concrete-type mappings using the injected `_unityContainer`:
* `IPSDReportSettingsViewModel``PSDReportSettingsViewModel`
* `IPSDReportSettingsModel``PSDReportSettingsModel`
* `IPSDReportSettingsView``PSDReportSettingsView`
**`PSDReportSettingsModuleNameAttribute`**
Inherits from: `TextAttribute`
* `[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]`
* `PSDReportSettingsModuleNameAttribute()`: Default constructor.
* `PSDReportSettingsModuleNameAttribute(string s)`: Overloaded constructor (parameter `s` is unused).
* `string AssemblyName { get; }`: Overrides the base property. Returns the string representation of `AssemblyNames.PSDReportSettings`.
* `Type GetAttributeType()`: Returns `typeof(TextAttribute)`.
* `string GetAssemblyName()`: Returns the value of the `AssemblyName` property.
**`PSDReportSettingsModuleImageAttribute`**
Inherits from: `ImageAttribute`
* `[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]`
* `PSDReportSettingsModuleImageAttribute()`: Default constructor.
* `PSDReportSettingsModuleImageAttribute(string s)`: Overloaded constructor (parameter `s` is unused).
* `BitmapImage AssemblyImage { get; }`: Returns a `BitmapImage` retrieved via `AssemblyInfo.GetImage(AssemblyNames.PSDReportSettings.ToString())`.
* `string AssemblyName { get; }`: Returns the string representation of `AssemblyNames.PSDReportSettings`.
* `string AssemblyGroup { get; }`: Returns `eAssemblyGroups.Viewer.ToString()`.
* `eAssemblyRegion AssemblyRegion { get; }`: Returns `eAssemblyRegion.PSDReportSettingsRegion`.
* `Type GetAttributeType()`: Returns `typeof(ImageAttribute)`.
* `BitmapImage GetAssemblyImage()`: Returns `AssemblyImage`.
* `string GetAssemblyName()`: Returns `AssemblyName`.
* `string GetAssemblyGroup()`: Returns `AssemblyGroup`.
* `eAssemblyRegion GetAssemblyRegion()`: Returns `AssemblyRegion`.
## 3. Invariants
* **Module Name:** The module is identified by the string `"PSDReportSettings"` in the `[Module]` attribute.
* **Assembly Group:** The module belongs to the `Viewer` assembly group (defined by `eAssemblyGroups.Viewer`).
* **Region:** The module is associated with the `PSDReportSettingsRegion` (defined by `eAssemblyRegion.PSDReportSettingsRegion`).
* **Registration:** The types `IPSDReportSettingsViewModel`, `IPSDReportSettingsModel`, and `IPSDReportSettingsView` are registered with the Unity container as transient types (default `RegisterType` behavior) upon module initialization.
## 4. Dependencies
**Internal Dependencies (referenced types):**
* `DTS.Common`: Uses `AssemblyNames` enum.
* `DTS.Common.Interface`: Uses `TextAttribute`, `ImageAttribute`, `eAssemblyGroups`, `eAssemblyRegion`. Also implies the existence of `IPSDReportSettingsViewModel`, `IPSDReportSettingsModel`, and `IPSDReportSettingsView` interfaces.
* `DTS.Viewer.PSDReportSettings`: Uses `PSDReportSettingsViewModel`, `PSDReportSettingsModel`, `PSDReportSettingsView` concrete classes and `AssemblyInfo` static class.
**External Frameworks:**
* `Prism.Ioc`: Uses `IContainerProvider`, `IContainerRegistry`.
* `Prism.Modularity`: Uses `IModule`, `ModuleAttribute`.
* `Unity`: Uses `IUnityContainer`.
* `System.Windows.Media.Imaging`: Uses `BitmapImage`.
## 5. Gotchas
* **Ignored Constructor Parameters:** Both `PSDReportSettingsModuleNameAttribute` and `PSDReportSettingsModuleImageAttribute` have constructors that accept a `string s` parameter, but this parameter is completely ignored in the logic. It is unclear why this parameter exists.
* **Mixed Container Usage:** The `RegisterTypes` method receives an `IContainerRegistry` (Prism abstraction) but the actual registration logic inside `Initialize()` uses the injected `IUnityContainer` (Unity specific). This bypasses the Prism abstraction layer, which could cause issues if the container implementation details differ or if the container wrapper is expected to manage lifestyle scopes.
* **Property Getter Side Effects:** In `PSDReportSettingsModuleImageAttribute`, the `AssemblyImage` property getter performs a method call `AssemblyInfo.GetImage(...)` and assigns it to the private field `_img` every time the getter is accessed. This is not a pure getter; it causes a new image lookup (and potentially a new object allocation) on every read access, rather than returning a cached value.
* **Empty OnInitialized:** The `OnInitialized` method is empty. If the module requires runtime initialization logic (like starting services or registering region views), it is not present here. The module currently only performs type registration.

View File

@@ -0,0 +1,99 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReportSettings/Model/PSDReportSettingsModel.cs
generated_at: "2026-04-16T11:01:19.271156+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "b9213b8d6a0e210e"
---
# Documentation: PSDReportSettingsModel
## 1. Purpose
`PSDReportSettingsModel` is a model class that stores and manages configuration settings for Power Spectral Density (PSD) report generation within the DTS Viewer application. It encapsulates filter parameters (low-pass and high-pass), windowing configuration (width, type, averaging, overlapping), and data range boundaries. The class implements `INotifyPropertyChanged` via `BasePropertyChanged` and coordinates with a parent view model through the `IPSDReportSettingsModel` interface, automatically notifying the parent of changes when `CanPublishChanges` is enabled.
---
## 2. Public Interface
### Properties
| Property | Type | Default Value | Description |
|----------|------|---------------|-------------|
| `Parent` | `IPSDReportSettingsViewModel` | `null` | Reference to the parent view model. Setter includes equality check to avoid redundant updates. |
| `CanPublishChanges` | `bool` | `true` | Controls whether property changes trigger `Parent.PublishChanges()` notification. |
| `LowPassFilterEnabled` | `bool` | `false` | Enables/disables low-pass filter. Sets `ReadData = true` on change. |
| `LowPassFilterFrequency` | `double` | `2000` | Low-pass filter cutoff frequency. Sets `ReadData = true` on change. |
| `LowPassFilterType` | `PassFilterType` | `PassFilterType.Butterworth` | Low-pass filter algorithm type. Sets `ReadData = true` on change. |
| `LowPassFilterOrder` | `int` | `8` | Low-pass filter order. Sets `ReadData = true` on change. |
| `HighPassFilterEnabled` | `bool` | `false` | Enables/disables high-pass filter. Sets `ReadData = true` on change. |
| `HighPassFilterFrequency` | `double` | `5` | High-pass filter cutoff frequency. Sets `ReadData = true` on change. |
| `HighPassFilterType` | `PassFilterType` | `PassFilterType.Butterworth` | High-pass filter algorithm type. Sets `ReadData = true` on change. |
| `HighPassFilterOrder` | `int` | `8` | High-pass filter order. Sets `ReadData = true` on change. |
| `WindowWidth` | `WindowWidth` | `WindowWidth.FortyNinetySix` | Window width for spectral analysis. Sets `ReadData = true` on change. |
| `WindowType` | `WindowType` | `WindowType.Hanning` | Window function type. Sets `ReadData = true` on change. |
| `WindowAveragingType` | `WindowAveragingType` | `WindowAveragingType.Averaging` | Averaging method for windows. Sets `ReadData = true` on change. |
| `WindowOverlappingPercent` | `double` | `50` | Window overlap percentage. Sets `ReadData = true` on change. |
| `ShowEnvelope` | `bool` | `false` | Controls envelope display. Sets `ReadData = true` on change. |
| `IsSaved` | `bool` | *(not visible)* | Read-only property indicating save state. No setter visible in source. |
| `ReadData` | `bool` | `false` | Flag indicating whether data should be re-read. |
| `DataStart` | `double` | `0D` | Start boundary for data range. Sets `ReadData = true` on change. |
| `DataEnd` | `double` | `0D` | End boundary for data range. Sets `ReadData = true` on change. |
### Methods
| Method | Signature | Description |
|--------|-----------|-------------|
| `OnPropertyChanged` | `void OnPropertyChanged(string propertyName)` | Override that raises `PropertyChanged` event and conditionally calls `Parent?.PublishChanges()` unless the property is `CanPublishChanges`, `Parent`, or `ReadData`. |
### Events
| Event | Type | Description |
|-------|------|-------------|
| `PropertyChanged` | `PropertyChangedEventHandler` | Override of base event; raised when any property value changes. |
---
## 3. Invariants
1. **ReadData Side Effect**: The following properties always set `ReadData = true` when modified:
- `LowPassFilterEnabled`, `LowPassFilterFrequency`, `LowPassFilterType`, `LowPassFilterOrder`
- `HighPassFilterEnabled`, `HighPassFilterFrequency`, `HighPassFilterType`, `HighPassFilterOrder`
- `WindowWidth`, `WindowType`, `WindowAveragingType`, `WindowOverlappingPercent`, `ShowEnvelope`
- `DataStart`, `DataEnd`
2. **Publishing Exclusion**: Changes to `CanPublishChanges`, `Parent`, or `ReadData` do **not** trigger `Parent.PublishChanges()`.
3. **Publishing Gate**: `Parent?.PublishChanges()` is only invoked when `CanPublishChanges == true`.
4. **Parent Equality Check**: The `Parent` property setter checks `_parent != null && _parent.Equals(value)` before updating, preventing redundant property change notifications.
5. **IsSaved Immutability**: `IsSaved` has no setter visible in the source; its value is determined externally (possibly via constructor or reflection).
---
## 4. Dependencies
### This Module Depends On:
- `DTS.Common.Enums.Viewer.Reports` — Provides `PassFilterType`, `WindowWidth`, `WindowType`, `WindowAveragingType` enums
- `DTS.Common.Interface` — Provides `IPSDReportSettingsViewModel` interface
- `Common.Base.BasePropertyChanged` — Base class providing `SetProperty` method and `INotifyPropertyChanged` infrastructure
### Consumers (Inferred):
- Any module implementing `IPSDReportSettingsViewModel` (the parent view model)
- Any code referencing `IPSDReportSettingsModel` interface
---
## 5. Gotchas
1. **ReadData Never Auto-Resets**: Setting `ReadData = true` via property changes never automatically resets it back to `false`. The consuming code must manage this flag's lifecycle.
2. **IsSaved Has No Setter**: The `IsSaved` property is read-only with no initialization visible in this file. Its value must be set through a mechanism not shown in the source (possibly constructor injection, reflection, or partial class extension).
3. **Parent Can Be Null**: The `Parent` property is not validated for null before use in `OnPropertyChanged`. While `Parent?.PublishChanges()` uses null-conditional operator, if `Parent` is null during other operations, behavior is undefined.
4. **Inconsistent Setter Patterns**: The `Parent` setter uses manual equality checking and `OnPropertyChanged("Parent")`, while most other properties use `SetProperty()`. The `CanPublishChanges` setter uses direct field assignment with `OnPropertyChanged("CanPublishChanges")`. This inconsistency may lead to subtle behavioral differences.
5. **No Validation on Numeric Inputs**: Properties like `LowPassFilterFrequency`, `HighPassFilterFrequency`, `WindowOverlappingPercent`, `DataStart`, and `DataEnd` accept any `double` value without bounds checking. Invalid values (e.g., negative frequencies, overlapping > 100) are not prevented at the model level.

View File

@@ -0,0 +1,40 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReportSettings/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T11:00:33.367677+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "86a096c3d5cd87e0"
---
# Documentation: DTS.Viewer.PSDReportSettings Assembly Configuration
## 1. Purpose
This file provides assembly-level metadata and configuration for the `DTS.Viewer.PSDReportSettings` component within the DTS Viewer application. It defines the assembly's identity, version information, and COM visibility settings using .NET attributes. As a standard `AssemblyInfo.cs` file, it serves as the manifest entry point for the compiled DLL, ensuring the module is correctly identified by the .NET runtime and host application.
## 2. Public Interface
This file does not contain executable classes or methods. It exposes the following assembly-level attributes as its public interface:
* **`AssemblyTitle("DTS.Viewer.PSDReportSettings")`**: Specifies the display name for the assembly.
* **`AssemblyProduct("DTS.Viewer.PSDReportSettings")`**: Specifies the product name associated with this assembly.
* **`AssemblyVersion("1.0.0.0")`**: Specifies the version number of the assembly used by the common language runtime.
* **`AssemblyFileVersion("1.0.0.0")`**: Specifies the Win32 file version resource; typically mirrors the assembly version.
* **`ComVisible(false)`**: Indicates that types within this assembly are not visible to COM components by default.
* **`Guid("82faae11-3be9-4223-beb8-8a53643866f8")`**: Specifies a unique identifier for the assembly if it is exposed to COM.
## 3. Invariants
* **COM Visibility:** The attribute `[assembly: ComVisible(false)]` ensures that no types within this assembly are exposed to COM unless a specific type is explicitly marked as visible.
* **Versioning:** Both the logical assembly version and the physical file version are currently fixed at `1.0.0.0`.
* **Identity:** The assembly is identified by the title `DTS.Viewer.PSDReportSettings` and the GUID `82faae11-3be9-4223-beb8-8a53643866f8`.
## 4. Dependencies
* **Internal Dependencies:**
* `System.Reflection`: Required for the assembly attribute definitions.
* `System.Runtime.CompilerServices`: Required for assembly attribute support.
* `System.Runtime.InteropServices`: Required for the `ComVisible` and `Guid` attributes.
* **External Dependencies:** None identified from this source file alone. The module name suggests it is a plugin or sub-module of the larger `DTS Viewer` system.
## 5. Gotchas
* **Hardcoded Versions:** The `AssemblyVersion` and `AssemblyFileVersion` are hardcoded to `1.0.0.0`. If the project uses Continuous Integration (CI) to auto-increment versions, this file may override those settings or require manual updating during releases.
* **SDK-Style Projects:** If this project is migrated to the modern SDK-style `.csproj` format, the attributes defined here may conflict with auto-generated attributes, resulting in compiler warnings (CS0579) regarding duplicate attributes.
* **Missing Metadata:** The `AssemblyDescription`, `AssemblyConfiguration`, `AssemblyCompany`, and `AssemblyTrademark` attributes are initialized as empty strings, which may result in missing metadata in the compiled DLL properties.

View File

@@ -0,0 +1,118 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReportSettings/Resources/TranslateExtension.cs
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReportSettings/Resources/StringResources.Designer.cs
generated_at: "2026-04-16T11:00:37.156668+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "5a446a4aa0389800"
---
# Documentation: DTS.Viewer.PSDReportSettings.Resources
## 1. Purpose
This module provides localization/translation infrastructure for the PSD (Power Spectral Density) Report Settings UI within the DTS Viewer application. It consists of a WPF XAML markup extension (`TranslateExtension`) that enables declarative resource binding in XAML, and a strongly-typed auto-generated resource accessor class (`StringResources`) containing localized strings for filter configurations, window settings, envelope display options, and export functionality.
---
## 2. Public Interface
### `TranslateExtension` (class)
**Namespace:** `DTS.Viewer.PSDReportSettings`
**Inheritance:** `MarkupExtension`
**Attribute:** `[MarkupExtensionReturnType(typeof(string))]`
A WPF markup extension that resolves localization keys to localized strings at XAML parse time.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `TranslateExtension(string key)` | Initializes the extension with the resource key to look up. The key is stored in a readonly field `_key`. |
| Method | `object ProvideValue(IServiceProvider serviceProvider)` | Returns the localized string for `_key` from `StringResources.ResourceManager`. Returns `#stringnotfound#` if `_key` is null or empty. Returns `#stringnotfound# <key>` if the key does not exist in the resource file. |
---
### `StringResources` (class)
**Namespace:** `DTS.Viewer.PSDReportSettings.Resources`
**Access:** `internal`
**Attribute:** `[GeneratedCode]`, `[DebuggerNonUserCode]`, `[CompilerGenerated]`
An auto-generated strongly-typed resource accessor class. **Not publicly accessible outside the assembly.**
| Member | Signature | Description |
|--------|-----------|-------------|
| Property | `static ResourceManager ResourceManager` | Lazily-initialized cached ResourceManager instance for the `DTS.Viewer.PSDReportSettings.Resources.StringResources` resource bundle. |
| Property | `static CultureInfo Culture` | Gets or sets the current UI culture for resource lookups. Overrides `Thread.CurrentUICulture` for this resource class. |
**Localized String Properties (all `internal static string`):**
| Property Name | Default Value (English) | Context |
|---------------|------------------------|---------|
| `EnvelopeHeader` | "Envelope" | UI header |
| `ExportPSDHeader` | "Export" | UI header |
| `ExportPSDtoCSV` | "Export PSD to CSV" | Export action |
| `ExportPSDtoPDF` | "Export PSD to PDF" | Export action |
| `FilterCenterFrequency` | "Center frequency" | Filter setting label |
| `FilterOrder` | "Filter order" | Filter setting label |
| `FilterSettingsHeader` | "Filters" | UI header |
| `FilterType` | "Filter type" | Filter setting label |
| `FilterType_Bessel` | "Bessel" | Filter type enum value |
| `FilterType_Butterworth` | "Butterworth" | Filter type enum value |
| `FilterType_LinkwitzRiley` | "Linkwitz-Riley" | Filter type enum value |
| `HighPassFilter` | "High pass filter" | Filter type |
| `Hz` | "Hz" | Unit label |
| `LowPassFilter` | "Low pass filter" | Filter type |
| `PSDSettingsHeader` | "PSD settings" | UI header |
| `ShowEnvelope` | "Show Envelope" | Checkbox/toggle label |
| `WindowAveragingType` | "Averaging type" | Window setting label |
| `WindowOverlappingPercent` | "Overlapping %" | Window setting label |
| `WindowSettingsHeader` | "Window" | UI header |
| `WindowType` | "Window type" | Window setting label |
| `WindowWidth` | "Window width" | Window setting label |
---
## 3. Invariants
1. **Key immutability:** The `_key` field in `TranslateExtension` is `readonly` and set only at construction time.
2. **Fallback behavior:** `ProvideValue` will never return `null`. It returns the constant `"#stringnotfound#"` for null/empty keys, or `"#stringnotfound# <key>"` for missing resource entries.
3. **ResourceManager singleton:** The `ResourceManager` property uses lazy initialization with a null-check pattern; once initialized, the same instance is returned for all subsequent calls.
4. **Thread-safety of ResourceManager:** The lazy initialization in `StringResources.ResourceManager` is **not thread-safe** (uses simple null check without locking). Concurrent access during first initialization could potentially create multiple ResourceManager instances.
5. **Internal visibility:** `StringResources` is marked `internal`, restricting access to within the `DTS.Viewer.PSDReportSettings` assembly.
---
## 4. Dependencies
### This module depends on:
- `System` (core types)
- `System.Windows.Markup` (`MarkupExtension`, `MarkupExtensionReturnTypeAttribute`)
- `System.Resources` (`ResourceManager`)
- `System.Globalization` (`CultureInfo`)
- `System.CodeDom.Compiler` (`GeneratedCodeAttribute`)
- `System.Diagnostics` (`DebuggerNonUserCodeAttribute`)
- `System.Runtime.CompilerServices` (`CompilerGeneratedAttribute`)
### External resource dependency:
- A `.resx` file (not shown in source) named `StringResources.resx` must exist in the `DTS.Viewer.PSDReportSettings.Resources` namespace to provide the actual localized values.
### What depends on this module:
- **Unclear from source alone.** The `TranslateExtension` is designed for XAML consumption within the PSD Report Settings UI, but the specific XAML files or controls using it are not present in the provided source.
---
## 5. Gotchas
1. **Auto-generated code warning:** `StringResources.Designer.cs` is tool-generated. Manual edits will be overwritten when the resource file is regenerated. The source explicitly warns: "Changes to this file may cause incorrect behavior and will be lost if the code is regenerated."
2. **Missing key visibility:** Missing localization keys result in visible error strings (`#stringnotfound#`) appearing in the UI rather than silent failures or exceptions. This is intentional for debugging but could leak into production if resource files are incomplete.
3. **Thread-safety gap:** The `ResourceManager` property getter performs a non-atomic check-then-assign pattern (`if (object.ReferenceEquals(resourceMan, null))`). Under concurrent access, multiple `ResourceManager` instances could be created, though the functional impact is likely minimal.
4. **Culture must be set explicitly:** The `StringResources.Culture` property allows overriding the current thread's UI culture, but it must be set manually. If never set, `resourceCulture` remains `null` and `ResourceManager.GetString` uses `Thread.CurrentUICulture`.
5. **No design-time validation:** The `TranslateExtension` constructor accepts any string key without validation. Typos in XAML will only manifest as `#stringnotfound#` at runtime.

View File

@@ -0,0 +1,54 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReportSettings/View/PSDReportSettingsView.xaml.cs
generated_at: "2026-04-16T11:00:59.568454+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "5b2351e33ed49693"
---
# Documentation: PSDReportSettingsView
## 1. Purpose
`PSDReportSettingsView` is a WPF view component that provides the user interface for configuring Power Spectral Density (PSD) report settings within the DTS Viewer application. It implements `IPSDReportSettingsView` and serves as the presentation layer for report configuration, exposing selectable options for spectral analysis parameters such as FFT window widths.
## 2. Public Interface
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `public PSDReportSettingsView()` | Initializes the view by calling `InitializeComponent()`, which loads the associated XAML layout. |
| Property | `public List<int> AvailableWindowWidths` | Returns a new list containing valid FFT window size options: `{ 512, 1024, 2048, 4096, 8192 }`. Each access creates a new list instance. |
**Implemented Interface:**
- `IPSDReportSettingsView` (from `DTS.Common.Interface`)
## 3. Invariants
- **Window width values are fixed**: The `AvailableWindowWidths` property always returns the same five integer values (512, 1024, 2048, 4096, 8192), representing power-of-two FFT sizes.
- **New instance per access**: `AvailableWindowWidths` creates and returns a new `List<int>` on every property getter invocation; it does not cache the collection.
- **XAML initialization required**: The constructor must call `InitializeComponent()` before the view can be used, as this is a code-behind for a XAML file.
## 4. Dependencies
**This module depends on:**
- `DTS.Common.Interface` — Provides the `IPSDReportSettingsView` interface that this class implements.
- `System.Collections.Generic` — Provides `List<T>` for the window widths collection.
- `Xceed.Wpf.Toolkit.PropertyGrid.Attributes` — Imported but **not used** in the visible source code.
- The corresponding XAML file (`PSDReportSettingsView.xaml`) — Paired via WPF partial class mechanism.
**What depends on this module:**
- Unclear from source alone. Consumers would reference this view through the `IPSDReportSettingsView` interface, likely a presenter or view model following a MVP/MVVM pattern.
## 5. Gotchas
- **Unused import**: The `Xceed.Wpf.Toolkit.PropertyGrid.Attributes` namespace is imported but no attributes or types from it are used in the visible code. This may be dead code or intended for future use.
- **Commented-out members**: Three properties (`AvailablePassFilterTypes`, `AvailableWindowAveragingTypes`, `AvailableWindowTypes`) and their backing fields are fully commented out. These referenced `IItemsSource` and enum item source classes from `DTS.Common.Enums.Viewer.Reports`. This suggests either:
- Incomplete refactoring
- Features moved elsewhere
- Work-in-progress that was disabled
- **Allocation on every access**: The `AvailableWindowWidths` property allocates a new `List<int>` on every call. If accessed frequently (e.g., in UI binding update loops), this could cause unnecessary garbage collection pressure. Consider caching if performance becomes an issue.
- **Interface contract unclear**: The `IPSDReportSettingsView` interface definition is not provided, so the expected contract beyond what's implemented here is unknown.

View File

@@ -0,0 +1,102 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReportSettings/ViewModel/PSDReportSettingsViewModel.cs
generated_at: "2026-04-16T11:00:01.546105+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "9dcac2937b5c346b"
---
# Documentation: PSDReportSettingsViewModel.cs
## 1. Purpose
This module provides a ViewModel for configuring PSD (Power Spectral Density) report settings within the DTS Viewer application. It acts as a mediator between the view layer and the data model, responding to graph-related events (channel selection, axis changes, graph clearing) and publishing setting changes to other system components via an event aggregator. The class follows the MVVM pattern using Prism framework conventions.
---
## 2. Public Interface
### Class: `PSDReportSettingsViewModel`
**Namespace:** `DTS.Viewer.PSDReportSettings`
**Inherits from:** `BaseViewModel<IPSDReportSettingsModel>`
**Implements:** `IPSDReportSettingsViewModel`
#### Properties
| Property | Type | Access | Description |
|----------|------|--------|-------------|
| `View` | `IBaseView` | get/set | Reference to the associated view; DataContext is set to `this` in constructor. |
| `Parent` | `IBaseViewModel` | get/set | Parent ViewModel reference, passed during initialization. |
| `Model` | `IPSDReportSettingsModel` | get/set | Hides base `Model` property. Backed by private `_model` field; raises `OnPropertyChanged("Model")` on set. |
| `NotificationRequest` | `InteractionRequest<Notification>` | get | Used to raise notification dialogs. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | get | Hides base property. Used to raise confirmation dialogs. |
#### Constructor
```csharp
public PSDReportSettingsViewModel(
IPSDReportSettingsView view,
IRegionManager regionManager,
IEventAggregator eventAggregator,
IUnityContainer unityContainer)
```
Initializes the ViewModel, sets the View's DataContext, creates interaction requests, and stores references to the event aggregator and Unity container.
#### Methods
| Method | Signature | Description |
|--------|-----------|-------------|
| `Initialize` | `override void Initialize()` | Empty override. No initialization logic. |
| `Initialize` | `override void Initialize(object parameter)` | Sets `Parent` from parameter, calls `Subscribe()`, resolves `IPSDReportSettingsModel` from container, and sets `Model.Parent = this`. |
| `PublishChanges` | `void PublishChanges()` | Publishes a `PSDReportSettingsChangedEvent` with a `PSDReportSettingsChangedEventArg` containing the current `Model` and `Parent`. |
---
## 3. Invariants
1. **Parent-Child Relationship:** The `Parent` property must be an `IBaseViewModel` type; it is cast directly from the `object parameter` in `Initialize(object parameter)` without null checking.
2. **Event Filtering:** Event handlers (`OnChartAxisChanged`, `OnGraphSelectedChannelsChanged`) filter events by checking `arg?.ParentVM != Parent`. Events not matching the parent are ignored.
3. **Model Resolution:** The `Model` is resolved from the Unity container during `Initialize(object parameter)`, not injected via constructor.
4. **Publish Control:** During X-axis changes in `OnChartAxisChanged`, `Model.CanPublishChanges` is set to `false` before modifying `DataStart`/`DataEnd`, then restored to `true` before calling `PublishChanges()`.
5. **DataContext Assignment:** The View's DataContext is assigned to `this` (the ViewModel) in the constructor, not to the Model (a commented line suggests this was previously different).
---
## 4. Dependencies
### Imports (this module depends on):
- `DTS.Common.Base` - Provides `BaseViewModel<T>`
- `DTS.Common.Events` - Provides event args: `ChartAxisChangedEventArg`, `GraphClearNotificationArg`, `GraphSelectedChannelsNotificationArg`, `PSDReportSettingsChangedEvent`, `PSDReportSettingsChangedEventArg`
- `DTS.Common.Interactivity` - Provides `InteractionRequest<T>`, `Notification`, `Confirmation`
- `DTS.Common.Interface` - Provides interfaces: `IBaseView`, `IBaseViewModel`, `IPSDReportSettingsModel`, `IPSDReportSettingsView`, `IPSDReportSettingsViewModel`
- `Prism.Events` - Provides `IEventAggregator`
- `Prism.Regions` - Provides `IRegionManager`
- `Unity` - Provides `IUnityContainer`
### Consumers (what depends on this module):
- Not determinable from this source file alone. Likely consumed by View classes and/or registered in a module initialization or DI container configuration.
---
## 5. Gotchas
1. **Member Hiding:** Both `Model` and `ConfirmationRequest` properties use the `new` keyword, hiding inherited members from `BaseViewModel<T>`. This could lead to unexpected behavior if the base class is accessed polymorphically.
2. **Commented-Out Code:** Several code blocks are commented out, including:
- A `Standalone` property
- Y-axis handling in `OnChartAxisChanged` (lines setting `MinFixedY`/`MaxFixedY`)
- `PublishChanges()` call in `OnGraphSelectedChannelsChanged`
- A subscription to `CursorsAlailableChangedEvent` in `Subscribe()`
This suggests incomplete features or work-in-progress that may cause confusion.
3. **Empty `Initialize()` Override:** The parameterless `Initialize()` method is empty. If base class calls this method, no initialization occurs.
4. **Direct Cast Without Validation:** In `Initialize(object parameter)`, the parameter is cast directly to `IBaseViewModel` without null or type checking, which could throw `InvalidCastException` or result in null.
5. **Unused `OnRaiseNotification` Method:** The `OnRaiseNotification` method is private with no apparent callers within this class. It may be dead code or intended for future use.

View File

@@ -0,0 +1,37 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Test/ViewerUnitTest.cs
generated_at: "2026-04-16T10:57:17.800691+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "59565ed277b22fcf"
---
# Documentation for `ViewerUnitTest.cs`
## 1. Purpose
This file defines a unit test class named `ViewerUnitTest` within the `DTS.Viewer.Test` namespace. It appears to be a skeleton or template file generated by the IDE, intended to house unit tests for the `DTS.Viewer` component. Currently, it serves as a placeholder with no implemented test logic.
## 2. Public Interface
* **`class ViewerUnitTest`**
* **Signature:** `public class ViewerUnitTest`
* **Description:** A container for unit tests, decorated with the `[TestClass]` attribute to indicate it contains test methods executable by the MSTest framework.
* **`void TestMethod1()`**
* **Signature:** `public void TestMethod1()`
* **Description:** A test method stub decorated with `[TestMethod]`. It currently takes no arguments, returns `void`, and contains no implementation logic or assertions.
## 3. Invariants
None identified from source alone. The class relies on the standard behavior of the MSTest framework regarding the execution of methods marked with `[TestMethod]`.
## 4. Dependencies
* **External Dependencies:**
* `Microsoft.VisualStudio.TestTools.UnitTesting`: Used for the `[TestClass]` and `[TestMethod]` attributes and the unit testing infrastructure.
* `System`: Standard System namespace (imported but not utilized in the current code).
* **Internal Dependencies:**
* None referenced within the file. While the namespace `DTS.Viewer.Test` implies a relationship with a `DTS.Viewer` project, no types from that project are instantiated or used in this specific file.
## 5. Gotchas
* **Empty Test Passes by Default:** The method `TestMethod1` is empty. In MSTest, an empty test method will execute successfully and return a "Passed" status. This may mislead developers into thinking valid test coverage exists when the method is effectively a no-op.
* **Template Code:** The naming convention (`TestMethod1`) and lack of implementation suggest this is raw template boilerplate code that has not yet been customized for specific business logic.

View File

@@ -0,0 +1,39 @@
---
source_files:
- DTS Viewer/DTS.Viewer.Test/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T10:58:23.127313+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "b0750861283679d4"
---
# Documentation: DTS.Viewer.Test Assembly Configuration
## 1. Purpose
This source file provides assembly-level metadata and configuration for the `DTS.Viewer.Test` project. It defines the identity, version, and COM visibility settings for the compiled test assembly. This file is standard boilerplate generated by Visual Studio for .NET Framework projects to manage build output attributes.
## 2. Public Interface
This file does not expose any classes, methods, or functions for programmatic invocation. It consists entirely of assembly-level attributes applied to the compiled DLL.
* **`[assembly: AssemblyTitle("DTS.Viewer.Test")]`**: Sets the friendly name for the assembly.
* **`[assembly: AssemblyDescription("")]`**: Provides a description; currently empty.
* **`[assembly: AssemblyVersion("1.0.0.0")]`**: Specifies the version number of the assembly used by the common language runtime.
* **`[assembly: AssemblyFileVersion("1.0.0.0")]`**: Specifies the file version number shown on the file properties dialog.
* **`[assembly: ComVisible(false)]`**: Indicates that types within this assembly are not visible to COM components.
* **`[assembly: Guid("d9980374-0c0d-4a27-90eb-b5af17fb419e")]`**: Specifies a unique identifier for the assembly, required if the assembly is ever exposed to COM.
## 3. Invariants
* **Versioning**: The assembly version and file version are currently locked to `1.0.0.0`. Any changes to the build process or release cycle must manually update these values in this file (or automate updating them).
* **COM Visibility**: The attribute `ComVisible(false)` is set globally. To expose a specific type to COM, that type must explicitly override this attribute with `[ComVisible(true)]`.
## 4. Dependencies
* **Internal Dependencies**: None defined in this file. Based on the project name `DTS.Viewer.Test`, it is inferred that this assembly references the main `DTS.Viewer` project and a unit testing framework (e.g., MSTest, NUnit, or xUnit), though these references are not visible in this specific source file.
* **External Dependencies**:
* `System.Reflection`: Required for the assembly attributes.
* `System.Runtime.CompilerServices`: Imported by default in Visual Studio templates, though not explicitly used by any attributes in this file.
* `System.Runtime.InteropServices`: Required for the `ComVisible` and `Guid` attributes.
## 5. Gotchas
* **Stagnant Versioning**: The version numbers are hardcoded strings (`"1.0.0.0"`). Unlike modern SDK-style projects which often derive versions from build pipelines or default to `1.0.0`, this file requires manual updates to reflect new releases.
* **Empty Metadata**: Several fields such as `AssemblyDescription`, `AssemblyCompany`, and `AssemblyConfiguration` are empty strings. This may result in sparse metadata in the compiled DLL properties.
* **Legacy Structure**: The existence of an explicit `AssemblyInfo.cs` suggests this is a legacy .NET Framework project structure. Modern .NET Core/5+ projects typically auto-generate this information, which can lead to build conflicts (CS0579) if this file is included in a modern SDK-style project without disabling auto-generation in the `.csproj` file.

View File

@@ -0,0 +1,178 @@
---
source_files:
- DTS Viewer/DTS.Viewer/Settings.cs
- DTS Viewer/DTS.Viewer/ExportModule.cs
- DTS Viewer/DTS.Viewer/ViewerModule.cs
- DTS Viewer/DTS.Viewer/ViewerSession.cs
- DTS Viewer/DTS.Viewer/Bootstrapper.cs
generated_at: "2026-04-16T10:57:48.975205+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "f841428d718c70bf"
---
# DTS.Viewer Module Documentation
## 1. Purpose
The `DTS.Viewer` namespace provides the core module infrastructure for a Prism-based WPF viewer application. It implements a modular architecture using Unity dependency injection and Prism's modularity framework, enabling dynamic loading of viewer and export functionality. The module manages application bootstrapping, session lifecycle, plugin discovery, and region-based view composition. It serves as the entry point for initializing the viewer shell, registering view/viewmodel pairs, and coordinating module communication via event aggregation.
---
## 2. Public Interface
### Settings (DTS.Viewer.Properties)
```csharp
internal sealed partial class Settings
```
- **Settings()** - Constructor with optional event handler registration (currently commented out).
- **SettingChangingEventHandler(object sender, SettingChangingEventArgs e)** - Handles the `SettingChanging` event before a setting's value is changed. Currently empty implementation.
- **SettingsSavingEventHandler(object sender, CancelEventArgs e)** - Handles the `SettingsSaving` event before settings are saved. Currently empty implementation.
### ExportModule
```csharp
[Module(ModuleName = "Export")]
public class ExportModule : IExportModule
```
- **ExportModule(IUnityContainer unityContainer)** - Constructor accepting an injected Unity container.
- **SessionStarted** (property: `bool`) - Indicates whether a session has been started. Set to `true` after `StartSession()` completes.
- **Initialize()** - Registers `IExportModule` to `ExportModule` with container-controlled lifetime.
- **StartSession()** - Resolves `IEventAggregator`, publishes `LoadExportModuleEvent` with `LoadExportModuleArg`, sets `SessionStarted = true`.
- **RegisterTypes(IContainerRegistry containerRegistry)** - Calls `Initialize()`.
- **OnInitialized(IContainerProvider containerProvider)** - Empty implementation.
### ExportNameAttribute
```csharp
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class ExportNameAttribute : TextAttribute
```
- **ExportNameAttribute()** - Default constructor, sets `_assemblyName = "Export"`.
- **ExportNameAttribute(string s)** - Parameterized constructor, ignores parameter and sets `_assemblyName = "Export"`.
- **AssemblyName** (property: `string`) - Returns `_assemblyName` ("Export").
- **GetAttributeType()** - Returns `typeof(TextAttribute)`.
- **GetAssemblyName()** - Returns `AssemblyName`.
### ViewerModule
```csharp
[Module(ModuleName = "Viewer")]
public class ViewerModule : IViewerModule
```
- **ViewerModule(IUnityContainer unityContainer)** - Constructor accepting an injected Unity container.
- **SessionStarted** (property: `bool`) - Indicates whether a session has been started.
- **Initialize()** - Registers `IViewerModule` to `ViewerModule` with container-controlled lifetime.
- **StartSession()** - Resolves `IEventAggregator`, publishes `LoadViewModulEvent` with `LoadViewModulArg`, sets `SessionStarted = true`.
- **RegisterTypes(IContainerRegistry containerRegistry)** - Calls `Initialize()`.
- **OnInitialized(IContainerProvider containerProvider)** - Empty implementation.
### ViewerNameAttribute
```csharp
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class ViewerNameAttribute : TextAttribute
```
- **ViewerNameAttribute()** - Default constructor, sets `_assemblyName = "Viewer"`.
- **ViewerNameAttribute(string s)** - Parameterized constructor, ignores parameter and sets `_assemblyName = "Viewer"`.
- **AssemblyName** (property: `string`) - Returns `_assemblyName` ("Viewer").
- **GetAttributeType()** - Returns `typeof(TextAttribute)`.
- **GetAssemblyName()** - Returns `AssemblyName`.
### ViewerSession
```csharp
public class ViewerSession
```
- **Container** (property: `IUnityContainer`) - Gets the Unity container after `CreateSession()` is called.
- **_serviceLocator** (property: `IServiceLocator`) - Gets the service locator after `CreateSession()`.
- **_eventAggregator** (property: `IEventAggregator`) - Gets the event aggregator after `CreateSession()`.
- **_regionManager** (property: `IRegionManager`) - Gets the region manager after `CreateSession()`.
- **CustomConfigPath** (property: `string`) - Gets/sets custom configuration path for plugin loading.
- **ViewerSession()** - Empty constructor.
- **CreateSession(bool standalone, string customConfigPath = "")** - Creates the bootstrapper, initializes container/services, loads plugins via `PluginManager`, and publishes `AssemblyListNotificationViewer` event.
- **Terminate()** - Called during JMPS shutdown. Empty implementation.
### Bootstrapper
```csharp
public class Bootstrapper : UnityBootstrapper
```
- **Bootstrapper(bool standalone, string customConfigPath = "")** - Constructor accepting standalone mode flag and optional custom config path.
- **Standalone** (property: `bool`) - Gets/sets whether running in standalone mode.
- **CustomConfigPath** (property: `string`) - Gets/sets custom configuration path.
- **_ServiceLocator** (property: `IServiceLocator`) - Gets the service locator after `CreateShell()`.
- **_EventAggregator** (property: `IEventAggregator`) - Gets the event aggregator after `CreateShell()`.
- **ConfigureContainer()** - Registers `IViewerMainViewGrid` to `ViewerMainViewGrid` and `IViewerMainViewModel` to `ViewerMainViewModel` (singleton).
- **ConfigureRegionAdapterMappings()** - Registers region adapters for `Selector`, `ItemsControl`, `ContentControl`, and conditionally `StackPanel` (standalone only). Uses try/catch to ignore already-registered mappings.
- **CreateShell()** - Creates the main shell, resolves `IViewerMainViewModel`, registers regions, sets DataContext, and initializes the view model. Returns `DependencyObject` or `null` on exception.
- **CreateModuleCatalog()** - Returns resolved `IModuleCatalog` or new `AggregateModuleCatalog`.
- **ConfigureModuleCatalog()** - In standalone mode, reads plugin folders from config section `DTS.Common.Core.PluginLib.Config` under key `viewerPlugins`, creates `DirectoryModuleCatalog`.
- **InitializeModules()** - In standalone mode, registers `IDTSViewRegionManager` to `DTSViewRegionManager` (singleton), then calls base implementation.
---
## 3. Invariants
1. **Bootstrapper Singleton**: The `ViewerSession._bootstrapper` field should only be created once. The `CreateBootstrapper` method checks for null before creating a new instance.
2. **Session State Consistency**: Both `ExportModule.SessionStarted` and `ViewerModule.SessionStarted` are `false` by default and only set to `true` after `StartSession()` publishes its respective event.
3. **Module Registration Pattern**: Both `ExportModule` and `ViewerModule` register themselves as implementations of their respective interfaces using `ContainerControlledLifetimeManager` (singleton behavior within the container).
4. **Standalone Mode Behavior**:
- `ConfigureModuleCatalog()` only loads directory-based modules when `Standalone == true`.
- `InitializeModules()` only registers `IDTSViewRegionManager` when `Standalone == true`.
- `ConfigureRegionAdapterMappings()` only registers `StackPanel` adapter when `Standalone == true`.
5. **Attribute Constructor Behavior**: Both `ExportNameAttribute` and `ViewerNameAttribute` ignore their string parameter in the parameterized constructor, always returning hardcoded "Export" or "Viewer" respectively.
6. **Region Registration**: In `CreateShell()`, regions are only added if they don't already exist (`ContainsRegionWithName` check).
---
## 4. Dependencies
### External Dependencies (Imports)
| Namespace | Purpose |
|-----------|---------|
| `DTS.Common.Events` | Event types: `LoadExportModuleEvent`, `LoadViewModulEvent`, `AssemblyListNotificationViewer` |
| `DTS.Common.Interface` | Interfaces: `IExportModule`, `IViewerModule`, `IViewerMainViewGrid`, `IViewerMainViewModel`, `IShellViewModel`, `IDTSViewRegionManager` |
| `DTS.Common.Core.PluginLib` | `PluginManager`, `PluginConfigSectionHandler`, `FilterHashElement`, `AssemblyListInfo` |
| `DTS.Common.Base` | `TextAttribute` base class |
| `Prism.Events` / `Microsoft.Practices.Prism.Events` | `IEventAggregator`, event base classes |
| `Prism.Ioc` | `IContainerRegistry`, `IContainerProvider` |
| `Prism.Modularity` / `Microsoft.Practices.Prism.Modularity` | `IModule`, `IModuleCatalog`, `ModuleAttribute`, `AggregateModuleCatalog`, `DirectoryModuleCatalog` |
| `Prism.Regions` / `Microsoft.Practices.Prism.Regions` | `IRegionManager`, `Region`, `RegionAdapterMappings`, region adapters |
| `Unity` / `Microsoft.Practices.Unity` | `IUnityContainer`, `ContainerControlledLifetimeManager`, `InjectionMember` |
| `Microsoft.Practices.ServiceLocation` | `IServiceLocator`, `ServiceLocator` |
| `System.Configuration` | `ConfigurationManager`, configuration section handling |
| `System.ComponentModel.Composition.Hosting` | MEF composition support |
### Downstream Dependencies
The following types are registered by this module and expected to be consumed by other components:
- `IExportModule``ExportModule`
- `IViewerModule``ViewerModule`
- `IViewerMainViewGrid``ViewerMainViewGrid`
- `IViewerMainViewModel``ViewerMainViewModel`
- `IDTSViewRegionManager``DTSViewRegionManager`
---
## 5. Gotchas
1. **Ignored Constructor Parameter**: Both `ExportNameAttribute(string s)` and `ViewerNameAttribute(string s)` accept a string parameter but completely ignore it, always returning hardcoded values. This is misleading API design.
2. **Mixed Prism Namespace Versions**: The code imports from both legacy `Microsoft.Practices.Prism.*` namespaces and newer `Prism.*` namespaces. This suggests a migration in progress or dependency on both old and new Prism versions.
3. **Bootstrapper Memory Footprint**: The comment in `ViewerSession` notes: *"It appears that the current bootstrapper loads around 40 MB into memory. To completely unload the bootstrapper would take same research and effort."* There is currently no mechanism to unload or recreate the bootstrapper.
4. **Empty Event Handlers**: `Settings.SettingChangingEventHandler` and `Settings.SettingsSavingEventHandler` have empty implementations with only placeholder comments.
5. **Silent Failures in Region Adapter Registration**: `ConfigureRegionAdapterMappings()` uses empty catch blocks (`try { ... } catch { }`) when registering region adapters, silently ignoring any registration failures.
6. **Exception Swallowing in CreateShell**: The `CreateShell()` method catches all exceptions, stores the message in a local variable `s` that is never used, and returns `null`. This makes debugging shell creation failures difficult.
7. **Commented-Out Code in ConfigureContainer**: There is significant commented-out code for conditional view registration based on `Standalone` mode, suggesting unfinished or experimental functionality.
8. **Redundant Null Check Pattern**: In `CreateBootstrapper`, the method checks `_bootstrapper == null` twice—once before the try block and once after, throwing an exception if still null. The inner catch already wraps and rethrows with context.
9. **Private Field Naming Convention**: Several fields use underscore prefix but are exposed via public properties with different names (e.g., `_customConfigPath` vs `CustomConfigPath`), while others like `_serviceLocator` have public getters but inconsistent naming.
10. **Module Self-Registration**: Both `ExportModule` and `ViewerModule` register themselves in `Initialize()`, which is called from `RegisterTypes()`. This is unusual—typically the container is configured before module initialization, not by the module itself.

View File

@@ -0,0 +1,117 @@
---
source_files:
- DTS Viewer/DTS.Viewer/Classes/MenuItem.cs
- DTS Viewer/DTS.Viewer/Classes/TabItem.cs
- DTS Viewer/DTS.Viewer/Classes/NavigationItem.cs
- DTS Viewer/DTS.Viewer/Classes/BindingProxy.cs
- DTS Viewer/DTS.Viewer/Classes/ComplonentsGroupControl.cs
generated_at: "2026-04-16T11:22:34.808193+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "e704fa30e232a4ba"
---
# Documentation: DTS.Viewer Classes
## 1. Purpose
This module provides a collection of UI support classes for the DTS Viewer WPF application. It includes data binding helpers (`BindingProxy`), custom controls (`ComponentsGroupControl`), and placeholder model classes (`MenuItem`, `TabItem`, `NavigationItem`) that appear to support the application's navigation and presentation layer. The module exists to enable XAML-specific features like data binding in non-visual contexts and to provide reusable UI components.
---
## 2. Public Interface
### `DTS.Viewer.BindingProxy`
A `Freezable`-derived class that enables data binding in contexts where the DataContext is not naturally inherited (e.g., from within a Style or DataTrigger).
| Member | Signature | Description |
|--------|-----------|-------------|
| `DataProperty` | `public static readonly DependencyProperty` | Dependency property backing store for `Data`. Registered with name `"Data"`, type `object`, owner type `BindingProxy`. |
| `Data` | `public object Data { get; set; }` | Gets or sets an arbitrary data object for binding purposes. Uses `GetValue`/`SetValue` on `DataProperty`. |
| `CreateInstanceCore` | `protected override Freezable CreateInstanceCore()` | Required override for `Freezable`. Returns a new instance of `BindingProxy`. |
---
### `DTS.Viewer.ComponentsGroupControl`
A custom `Control` for displaying a grouped component with an image and title.
| Member | Signature | Description |
|--------|-----------|-------------|
| `ClickEventArgs` | `public class ClickEventArgs : EventArgs` | Nested class for click event arguments. Contains only a default constructor. |
| `ClickCommand` | `public static RoutedCommand ClickCommand { get; }` | Static routed command named `"ClickCommand"`. Returns the private `_click` field. |
| `ImageProperty` | `public static readonly DependencyProperty ImageProperty` | Dependency property for the `Image` property. Type `ImageSource`, default value `null`. |
| `Image` | `public ImageSource Image { get; set; }` | Gets or sets the image source displayed by the control. |
| `TitleProperty` | `public static readonly DependencyProperty TitleProperty` | Dependency property for the `Title` property. Type `string`, default value `"Title"`. |
| `Title` | `public string Title { get; set; }` | Gets or sets the title text displayed by the control. |
**Private/Static Members:**
- `private static RoutedCommand _click` — Backing field for `ClickCommand`.
- `private static void OnCommandExecute(object sender, ExecutedRoutedEventArgs e)` — Command handler; casts sender to `ComponentsGroupControl` but performs no further action.
- `private static void InitializeCommands()` — Registers the `ClickCommand` with `CommandManager`.
- `static ComponentsGroupControl()` — Static constructor that overrides `DefaultStyleKeyProperty` metadata and initializes commands.
---
### `DTS.Viewer.MenuItem`
An empty internal class with no members. Purpose unclear from source alone.
---
### `DTS.Viewer.Classes.TabItem`
An empty internal class with no members. Purpose unclear from source alone.
---
### `DTS.Viewer.Classes.NavigationItem`
An empty public class with no members. Purpose unclear from source alone.
---
## 3. Invariants
- **BindingProxy**: As a `Freezable` subclass, `CreateInstanceCore()` must always return a new instance of `BindingProxy` (currently satisfied).
- **ComponentsGroupControl**:
- The static constructor always runs before any instance is created, ensuring `DefaultStyleKeyProperty` metadata is overridden and commands are registered.
- `Title` property defaults to the string `"Title"` (via `UIPropertyMetadata`).
- `Image` property defaults to `null`.
- **Dependency Properties**: All dependency properties follow WPF conventions—registered with correct owner types and accessed via `GetValue`/`SetValue`.
---
## 4. Dependencies
### Imports (What this module depends on):
| Class | Dependencies |
|-------|--------------|
| `BindingProxy` | `System.Windows` (Freezable, DependencyProperty) |
| `ComponentsGroupControl` | `System`, `System.Windows`, `System.Windows.Controls`, `System.Windows.Input`, `System.Windows.Media` |
| `MenuItem`, `TabItem`, `NavigationItem` | None (no imports) |
### Dependents (What depends on this module):
**Cannot be determined from source alone.** These classes are likely referenced by XAML files, view models, or other code files not provided in this source set.
---
## 5. Gotchas
1. **`ComponentsGroupControl.OnCommandExecute` does nothing useful**: The method casts the sender to `ComponentsGroupControl` but performs no action afterward. The actual click handling logic is either missing or expected to be implemented elsewhere (possibly in XAML or a code-behind not shown).
2. **Commented-out code in `ComponentsGroupControl`**: Several members are commented out:
- `SubtitleProperty` and `Subtitle` property
- `TabItemProperty` and `TabItem` property (referencing a type `DataModel.TabPageItem`)
- `ClickEventHandler` delegate and `OnClicked` event
This suggests incomplete refactoring or features that were started but not finished.
3. **Empty placeholder classes**: `MenuItem`, `TabItem`, and `NavigationItem` have no members whatsoever. They may be stubs awaiting implementation, used only as markers in XAML, or remnants of abandoned development.
4. **Namespace inconsistency**: `MenuItem` is in `DTS.Viewer` namespace, while `TabItem` and `NavigationItem` are in `DTS.Viewer.Classes`. This inconsistency may cause confusion when locating classes.
5. **`ClickEventArgs` is defined but never used**: The nested `ClickEventArgs` class exists in `ComponentsGroupControl`, but the associated event (`OnClicked`) is commented out, making this class currently unused.

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

View File

@@ -0,0 +1,63 @@
---
source_files:
- DTS Viewer/DTS.Viewer/Properties/Settings.Designer.cs
- DTS Viewer/DTS.Viewer/Properties/AssemblyInfo.cs
- DTS Viewer/DTS.Viewer/Properties/Resources.Designer.cs
generated_at: "2026-04-16T11:23:58.003501+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "06945b304ce6ac54"
---
# Documentation: DTS.Viewer.Properties
## 1. Purpose
This module provides the auto-generated infrastructure for application settings, localized resource management, and assembly metadata for the **DTS.Viewer** application. It acts as the configuration and identity layer, enabling strongly-typed access to user preferences via the `Settings` class and culture-specific resource lookups via the `Resources` class. The `AssemblyInfo.cs` file defines the application's version, company attribution (Diversified Technical Systems, Inc.), and WPF theme resource locations.
## 2. Public Interface
### Class: `DTS.Viewer.Properties.Settings`
* **Signature**: `internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase`
* **Properties**:
* `public static Settings Default { get; }`: Returns the singleton instance of the application settings wrapper. This is the primary entry point for accessing application settings.
* **Behavior**: Provides a thread-safe singleton wrapper for application configuration. Note that the provided source contains no custom setting properties; they must be defined in the associated `.settings` file and regenerated into this partial class.
### Class: `DTS.Viewer.Properties.Resources`
* **Signature**: `internal class Resources`
* **Properties**:
* `internal static global::System.Resources.ResourceManager ResourceManager { get; }`: Returns the cached `ResourceManager` instance responsible for looking up localized resources (strings, images, etc.) within the "DTS.Viewer.Properties.Resources" scope.
* `internal static global::System.Globalization.CultureInfo Culture { get; set; }`: Gets or sets the current `CultureInfo` used for resource lookups. Overrides the thread's current UI culture for this resource manager.
* **Behavior**: Acts as a strongly-typed proxy for `.resx` files. Like the `Settings` class, the provided source shows only the infrastructure; specific resource properties (e.g., string constants) are auto-generated into this class based on the `.resx` content.
### Assembly Attributes (AssemblyInfo.cs)
* **Identity**:
* `[assembly: AssemblyTitle("DTS.Viewer")]`
* `[assembly: AssemblyCompany("Diversified Technical Systems, Inc. (DTS)")]`
* **Versioning**:
* `[assembly: AssemblyVersion("1.0.0.0")]`
* `[assembly: AssemblyFileVersion("1.0.0.0")]`
* **COM Visibility**: `[assembly: ComVisible(false)]` — Types are not visible to COM components.
* **Theming**: `[assembly: ThemeInfo(...)]` — Configures WPF to look for generic resource dictionaries in the source assembly.
## 3. Invariants
* **Singleton Guarantee**: The `Settings.Default` property is guaranteed to return a synchronized, thread-safe instance of the `Settings` class (enforced by `ApplicationSettingsBase.Synchronized`).
* **Lazy Initialization**: The `Resources.ResourceManager` property is lazily initialized; the internal `resourceMan` field remains `null` until the property is first accessed.
* **Code Generation**: Both `Settings` and `Resources` are marked with `GeneratedCodeAttribute`. Manual edits to these files will be overwritten by the tooling (Visual Studio Settings Designer or ResGen) during the next regeneration.
## 4. Dependencies
### Dependencies of this Module
* **System.Configuration**: Required for `ApplicationSettingsBase` (used by `Settings`).
* **System.Resources**: Required for `ResourceManager` (used by `Resources`).
* **System.Globalization**: Required for `CultureInfo` (used by `Resources`).
* **System.Windows**: Required for `ResourceDictionaryLocation` (used in `AssemblyInfo.cs` for WPF theming).
* **System.Reflection**, **System.Runtime.InteropServices**: Required for assembly-level metadata attributes.
### Dependents of this Module
* **DTS.Viewer Assembly**: All code within the `DTS.Viewer` project relies on `Properties.Settings.Default` for configuration persistence and `Properties.Resources` for localized strings and assets.
## 5. Gotchas
* **Auto-Generated Code Warning**: The source files `Settings.Designer.cs` and `Resources.Designer.cs` contain explicit warnings that manual changes will be lost. Developers must modify the underlying XML files (`.settings` and `.resx`) rather than the C# source.
* **Missing Custom Properties**: The provided source for `Settings` and `Resources` contains only the infrastructure code (singleton pattern and resource manager plumbing). No actual user settings or resource strings are visible in the provided text; this implies the specific data values are defined elsewhere (in XML) and injected during the build process.
* **Template Copyright**: The `AssemblyInfo.cs` file contains `AssemblyCopyright("Copyright © Microsoft 2016")`. This appears to be a default Visual Studio template value that was not updated to reflect the actual company ("Diversified Technical Systems, Inc. (DTS)").
* **Internal Visibility**: Both `Settings` and `Resources` are marked `internal`, meaning they are not accessible outside the `DTS.Viewer` assembly.

View File

@@ -0,0 +1,67 @@
---
source_files:
- DTS Viewer/DTS.Viewer/RegionAdapters/StackPanelRegionAdapter.cs
generated_at: "2026-04-16T11:23:32.925488+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "d99a52248dae627a"
---
# StackPanelRegionAdapter Documentation
## 1. Purpose
`StackPanelRegionAdapter` is a Prism region adapter that enables a WPF `StackPanel` control to act as a Prism region. It bridges the Prism region infrastructure with the `StackPanel`'s `Children` collection, automatically synchronizing views added to or removed from the region with the panel's visual children. This allows views to be dynamically composed within a `StackPanel` using Prism's region management system.
## 2. Public Interface
### `StackPanelRegionAdapter` (Class)
**Inherits from:** `RegionAdapterBase<StackPanel>`
#### Constructor
```csharp
public StackPanelRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
```
Initializes a new instance of the adapter, passing the region behavior factory to the base class.
#### Protected Methods
```csharp
protected override void Adapt(IRegion region, StackPanel regionTarget)
```
Subscribes to the `region.Views.CollectionChanged` event and synchronizes the `StackPanel`'s `Children` collection:
- On `NotifyCollectionChangedAction.Add`: Iterates `e.NewItems` and adds each `UIElement` to `regionTarget.Children`.
- On `NotifyCollectionChangedAction.Remove`: Iterates `e.OldItems` and removes each `UIElement` from `regionTarget.Children` if present.
- Returns immediately if `region` is `null`.
```csharp
protected override IRegion CreateRegion()
```
Creates and returns a new `AllActiveRegion` instance, indicating all views in this region are considered active simultaneously.
## 3. Invariants
- The `region` parameter in `Adapt()` must not be `null` for any synchronization to occur (method returns early otherwise).
- All items in `region.Views` must be castable to `UIElement`; the code performs a direct cast without type checking.
- The `regionTarget` must be a valid `StackPanel` instance.
- The adapter creates an `AllActiveRegion`, meaning all views added to this region will be active at once (as opposed to single-active regions like tabs).
## 4. Dependencies
### This module depends on:
- `System.Collections.Specialized` (`NotifyCollectionChangedAction`)
- `System.Windows` (`UIElement`)
- `System.Windows.Controls` (`StackPanel`)
- `Microsoft.Practices.Prism.Regions` (`IRegion`, `IRegionBehaviorFactory`, `RegionAdapterBase<T>`, `AllActiveRegion`)
### Consumers:
- This adapter must be registered with the Prism region adapter mappings (not shown in source) to be used for `StackPanel` controls.
## 5. Gotchas
- **Unhandled collection actions**: The `Adapt` method only handles `Add` and `Remove` actions. `Replace`, `Move`, and `Reset` actions from `NotifyCollectionChangedAction` are silently ignored, which could lead to desynchronization if the region's view collection triggers these actions.
- **No event unsubscription**: The `CollectionChanged` handler is never unsubscribed. If the adapter or region outlives the `StackPanel`, this could cause memory leaks or unexpected behavior.
- **Redundant variable assignment**: In the `Remove` case, `var element = elementLoopVariable;` creates an unnecessary local copy. This appears to be a legacy closure pattern but serves no purpose here since the variable is not captured.
- **No type safety on collection items**: The code casts `e.NewItems` and `e.OldItems` elements directly to `UIElement` without validation. Non-`UIElement` items will throw `InvalidCastException` at runtime.

View File

@@ -0,0 +1,107 @@
---
source_files:
- DTS Viewer/DTS.Viewer/Resources/TranslateExtension.cs
- DTS Viewer/DTS.Viewer/Resources/StringResources.Designer.cs
generated_at: "2026-04-16T11:23:12.329617+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "dbbc3094853fd65f"
---
# Documentation: DTS.Viewer.Resources Localization Module
## 1. Purpose
This module provides localization/internationalization support for the DTS Viewer WPF application. It enables XAML-based string lookup through a markup extension pattern, allowing UI elements to bind to localized resources declaratively. The `TranslateExtension` class serves as a bridge between XAML markup and the underlying `StringResources` resource manager, while `StringResources` provides strongly-typed, auto-generated access to localized strings stored in compiled resource files (.resx).
---
## 2. Public Interface
### `TranslateExtension` (Class)
**Namespace:** `DTS.Viewer`
**Attributes:** `[MarkupExtensionReturnType(typeof(string))]`
A WPF markup extension that resolves localization keys to their corresponding string values at runtime.
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `TranslateExtension(string key)` | Initializes the extension with the resource key to look up. Stores the key in a readonly field `_key`. |
| `ProvideValue` | `public override object ProvideValue(IServiceProvider serviceProvider)` | Returns the localized string for the provided key. Returns `NotFound` constant if key is null/empty, or `NotFound + " " + _key` if the key is not found in resources. |
| `NotFound` | `private const string NotFound = "#stringnotfound#"` | Fallback string returned when a key is invalid or missing. |
---
### `StringResources` (Class)
**Namespace:** `DTS.Viewer.Resources`
**Accessibility:** `internal`
**Attributes:** `[GeneratedCode]`, `[DebuggerNonUserCode]`, `[CompilerGenerated]`
An auto-generated strongly-typed resource class providing access to localized strings.
| Member | Signature | Description |
|--------|-----------|-------------|
| `ResourceManager` | `internal static global::System.Resources.ResourceManager ResourceManager { get; }` | Lazily-initialized, cached `ResourceManager` instance for the `DTS.Viewer.Resources.StringResources` resource bundle. |
| `Culture` | `internal static global::System.Globalization.CultureInfo Culture { get; set; }` | Gets or sets the current UI culture for resource lookups. Overrides `Thread.CurrentUICulture` for this resource class. |
**Localized String Properties (all `internal static string`):**
| Property | Default Value (from comments) |
|----------|-------------------------------|
| `ChartOptionsHeader` | "Chart Options" |
| `GraphsDefaultTitle` | "Graphs " |
| `ModificationsHeader` | "Modify" |
| `SavePDFError` | "Error occurred saving chart to PDF" |
| `SavePDFSuccess` | "Chart saved succesfully as {0}{1} and {2}{3}" |
| `SettingsTitle` | "Settings" |
| `TestIDsDefaultTitle` | "Test IDs" |
| `TestsDefaultTitle` | "Tests " |
---
## 3. Invariants
1. **Key immutability:** The `_key` field in `TranslateExtension` is `readonly` and set only at construction time.
2. **Null safety:** `ProvideValue` will never return null. It returns either the localized string, `NotFound` (for null/empty keys), or `NotFound + " " + _key` (for missing keys).
3. **ResourceManager singleton:** The `ResourceManager` property uses a check-then-create pattern with a temporary variable to ensure thread-safe lazy initialization.
4. **Resource name mapping:** The `ResourceManager` is initialized with the base name `"DTS.Viewer.Resources.StringResources"`, which must match the embedded resource path.
5. **Culture fallback:** If `Culture` property is not explicitly set (`resourceCulture` is null), `ResourceManager.GetString` uses the current thread's `CurrentUICulture`.
---
## 4. Dependencies
### This module depends on:
- `System` (core .NET types)
- `System.Windows.Markup` - for `MarkupExtension` base class and `MarkupExtensionReturnTypeAttribute`
- `System.Resources` - for `ResourceManager` class
- `System.Globalization` - for `CultureInfo` class
- `System.CodeDom.Compiler`, `System.Diagnostics`, `System.Runtime.CompilerServices` - for auto-generated attributes
- **Resource files (.resx)** - The actual localized string data backing `StringResources` (not included in source, but implied by the designer file)
### What depends on this module:
- **XAML files in DTS.Viewer** - Use `{x:Static res:StringResources.PropertyName}` or `{local:Translate KeyName}` syntax for localized strings
- **PDF export functionality** - Uses `SavePDFSuccess` and `SavePDFError` strings
- **Chart/Graph UI components** - Use `ChartOptionsHeader`, `GraphsDefaultTitle`, `ModificationsHeader`
- **Settings UI** - Uses `SettingsTitle`
- **Test-related UI** - Uses `TestIDsDefaultTitle`, `TestsDefaultTitle`
---
## 5. Gotchas
1. **`StringResources` is `internal`:** The class cannot be accessed from outside the `DTS.Viewer` assembly. External libraries cannot directly use these resources.
2. **Missing key behavior:** Missing localization keys do not throw exceptions. Instead, they return `"#stringnotfound# {key}"`, which may appear in production UI if resources are misconfigured. This is intentional fallback behavior but could mask configuration errors.
3. **Typo in resource string:** The `SavePDFSuccess` resource contains "succesfully" (missing one 'l') per the source comments. This typo originates from the .resx file, not the generated code.
4. **Trailing spaces:** `GraphsDefaultTitle` and `TestsDefaultTitle` have trailing spaces in their default values ("Graphs " and "Tests "). This may be intentional for UI layout but could cause issues if trimmed unexpectedly.
5. **Format string dependency:** `SavePDFSuccess` expects 4 format arguments (`{0}{1} and {2}{3}`). Callers must provide exactly 4 arguments or a `FormatException` will occur at runtime.
6. **Auto-generated file warning:** `StringResources.Designer.cs` is regenerated by tooling. Manual edits will be lost. The underlying `.resx` file is the source of truth.

View File

@@ -0,0 +1,82 @@
---
source_files:
- DTS Viewer/DTS.Viewer/View/TabView.xaml.cs
- DTS Viewer/DTS.Viewer/View/MenuView.xaml.cs
- DTS Viewer/DTS.Viewer/View/MainView.xaml.cs
- DTS Viewer/DTS.Viewer/View/ShellView.xaml.cs
- DTS Viewer/DTS.Viewer/View/ViewerShellView.xaml.cs
- DTS Viewer/DTS.Viewer/View/NavigationView.xaml.cs
generated_at: "2026-04-16T11:23:56.516498+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "c4a45b12e62dbb35"
---
# Documentation: DTS.Viewer Views
## 1. Purpose
This module contains the code-behind files for WPF views in the DTS Viewer application. It defines six view components (`TabView`, `MenuView`, `MainView`, `ShellView`, `ViewerShellView`, `NavigationView`) that serve as the visual layer of the application. Each view implements a corresponding interface from `DTS.Common.Interface`, enabling view abstraction—likely to support MVVM architecture, dependency injection, or unit testing. The views are thin wrappers around XAML definitions, with all interaction logic delegated to the XAML layer.
---
## 2. Public Interface
### `TabView`
- **Namespace:** `DTS.Viewer`
- **Implements:** `ITabView`
- **Constructor:** `public TabView()` — Initializes the component via `InitializeComponent()`.
### `MenuView`
- **Namespace:** `DTS.Viewer`
- **Implements:** `IMenuView`
- **Constructor:** `public MenuView()` — Initializes the component via `InitializeComponent()`.
### `MainView`
- **Namespace:** `DTS.Viewer`
- **Implements:** `IMainView`
- **Constructor:** `public MainView()` — Initializes the component via `InitializeComponent()`.
### `ShellView`
- **Namespace:** `DTS.Viewer.View`
- **Implements:** `IViewerShellView`
- **Constructor:** `public ShellView()` — Initializes the component via `InitializeComponent()`.
### `ViewerShellView`
- **Namespace:** `DTS.Viewer`
- **Implements:** `IViewerShellView`
- **Constructor:** `public ViewerShellView()` — Initializes the component via `InitializeComponent()`.
### `NavigationView`
- **Namespace:** `DTS.Viewer`
- **Implements:** `INavigationView`
- **Constructor:** `public NavigationView()` — Initializes the component via `InitializeComponent()`.
---
## 3. Invariants
- Each view class is declared `partial`, indicating the existence of a corresponding XAML file that completes the class definition at compile time.
- Each view implements exactly one interface from `DTS.Common.Interface`.
- The constructor for each view must call `InitializeComponent()` to load the associated XAML resources and UI definition.
- `ShellView` and `ViewerShellView` both implement the same interface (`IViewerShellView`), but reside in different namespaces.
---
## 4. Dependencies
### This module depends on:
- `DTS.Common.Interface` — Provides the interfaces (`ITabView`, `IMenuView`, `IMainView`, `IViewerShellView`, `INavigationView`) that each view implements.
### What depends on this module:
- **Unclear from source alone.** Consumers would typically include view composition logic, MVVM view models, or dependency injection containers that resolve these view types. The associated XAML files (not provided) would also define the visual structure and bindings.
---
## 5. Gotchas
1. **Duplicate interface implementation:** Both `ShellView` (in namespace `DTS.Viewer.View`) and `ViewerShellView` (in namespace `DTS.Viewer`) implement `IViewerShellView`. The reason for this duplication is unclear from source alone—it may indicate a refactoring in progress, a legacy artifact, or intentional separation for different contexts.
2. **Namespace inconsistency:** `ShellView` resides in `DTS.Viewer.View` while all other views reside directly in `DTS.Viewer`. This may cause confusion when resolving types or configuring dependency injection.
3. **No explicit behavior in code-behind:** All views contain only the constructor with `InitializeComponent()`. Any event handlers, commands, or UI logic must be defined in the XAML files (not provided) or handled via MVVM bindings.

View File

@@ -0,0 +1,61 @@
---
source_files:
- DTS Viewer/DTS.Viewer/View/DockPanelHorizontal/View/DockPanelHorizontalView.xaml.cs
generated_at: "2026-04-16T11:24:16.471740+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "5cdf7bb10effcdd4"
---
# Documentation: DockPanelHorizontalView
## 1. Purpose
`DockPanelHorizontalView` is a WPF view component representing a horizontal dock panel within the DTS Viewer application. It serves as the code-behind partial class for `DockPanelHorizontalView.xaml`, providing interaction logic for a horizontally-oriented docking layout element. This module exists to implement the `IDockPanelHorizontalView` interface, enabling it to be consumed by other components that depend on this abstraction.
---
## 2. Public Interface
### `DockPanelHorizontalView` (class)
**Namespace:** `DTS.Viewer`
**Implements:** `IDockPanelHorizontalView`
**Constructor:**
```csharp
public DockPanelHorizontalView()
```
Initializes a new instance of the `DockPanelHorizontalView` class and invokes `InitializeComponent()`, which loads and initializes the associated XAML-defined UI components.
**Note:** The base class is not explicitly declared in this file; it is defined in the corresponding XAML file (`DockPanelHorizontalView.xaml`) as is standard for WPF partial classes.
---
## 3. Invariants
- `InitializeComponent()` must be called exactly once during construction, before the view instance is used. This is enforced by the constructor implementation.
- The class must remain a `partial` class to allow the WPF compiler to merge the XAML-generated code with this code-behind.
- The view must properly implement `IDockPanelHorizontalView`, though the specific interface members are not visible in this source file.
---
## 4. Dependencies
**This module depends on:**
- `DTS.Common.Base` — Imported but no direct usage is visible in this file; likely provides base types or utilities.
- `DTS.Common.Interface` — Provides the `IDockPanelHorizontalView` interface that this class implements.
**What depends on this module:**
- Cannot be determined from this source file alone. Consumers would be components that require an `IDockPanelHorizontalView` implementation, likely within the DTS Viewer application's docking infrastructure.
---
## 5. Gotchas
- **Base class is undefined in source:** The parent class of `DockPanelHorizontalView` is declared in the XAML file (typically `UserControl`, `Window`, or a custom base). The inheritance hierarchy cannot be confirmed from this file alone.
- **Interface contract is opaque:** The members required by `IDockPanelHorizontalView` are not visible in this source. It is unclear whether the class should implement additional properties, methods, or events.
- **Unused import:** The `DTS.Common.Base` namespace is imported but no types from it are directly referenced in the visible code. This may indicate historical refactoring or base class inheritance defined in XAML.

View File

@@ -0,0 +1,114 @@
---
source_files:
- DTS Viewer/DTS.Viewer/View/DockPanelHorizontal/ViewModel/DockPanelHorizontalViewModel.cs
generated_at: "2026-04-16T11:24:34.196995+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "6bc81faa835eebdc"
---
# DockPanelHorizontalViewModel Documentation
## 1. Purpose
`DockPanelHorizontalViewModel` is a ViewModel component within a WPF/Prism-based application that manages the state and behavior of a horizontal dock panel UI element. It inherits from `BaseViewModel<IDockPanelHorizontalViewModel>` and implements `IDockPanelHorizontalViewModel`, serving as a coordinator between the view layer and the application's event system. The class provides notification/confirmation dialog support via Prism's `InteractionRequest` pattern and subscribes to application-wide `RaiseNotification` events.
---
## 2. Public Interface
### Constructor
```csharp
public DockPanelHorizontalViewModel(
IDockPanelHorizontalView view,
IRegionManager regionManager,
IEventAggregator eventAggregator,
IUnityContainer unityContainer)
```
Initializes the ViewModel, sets the View's `DataContext` to itself, creates `NotificationRequest` and `ConfirmationRequest` instances, stores dependencies, and subscribes to the `RaiseNotification` event via the `EventAggregator`.
### Properties
| Property | Type | Access | Description |
|----------|------|--------|-------------|
| `View` | `IDockPanelHorizontalView` | `public get; private set` | Reference to the associated view instance. |
| `NotificationRequest` | `InteractionRequest<Notification>` | `public get; private set` | Prism interaction request for displaying notifications. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | `public get; private set` | Prism interaction request for displaying confirmation dialogs. |
| `IsMenuIncluded` | `bool` | `public get; set` | Flag indicating whether a menu is included. |
| `IsNavigationIncluded` | `bool` | `public get; set` | Flag indicating whether navigation is included. |
| `IsBusy` | `bool` | `public get; set` | Flag indicating busy/loading state. |
| `IsDirty` | `bool` | `public get; private set` | Flag indicating unsaved changes state. |
### Events
```csharp
public event PropertyChangedEventHandler PropertyChanged;
```
Standard `INotifyPropertyChanged` event declaration.
### Methods
| Method | Return Type | Behavior |
|--------|-------------|----------|
| `Initialize()` | `void` | Throws `NotImplementedException`. |
| `Initialize(object parameter)` | `void` | Throws `NotImplementedException`. |
| `Activated()` | `void` | Throws `NotImplementedException`. |
| `Cleanup()` | `void` | Throws `NotImplementedException`. |
| `CleanupAsync()` | `Task` | Throws `NotImplementedException`. Marked with `new` keyword. |
| `Initialize(object parameter, object model)` | `void` | Throws `NotImplementedException`. Marked with `new` keyword. |
| `InitializeAsync()` | `Task` | Throws `NotImplementedException`. |
| `InitializeAsync(object parameter)` | `Task` | Throws `NotImplementedException`. |
### Private Methods
```csharp
private void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)
```
Event handler for `RaiseNotification` events. Extracts `Message`, `MessageDetails`, `Image`, and `Title` from the received `NotificationContentEventArgs`, constructs a new `NotificationContentEventArgs` (without title), and raises the `NotificationRequest` with a `Notification` containing the reconstructed content and separate title.
---
## 3. Invariants
- The `View.DataContext` is set to `this` (the ViewModel instance) upon construction and is never changed.
- `NotificationRequest` and `ConfirmationRequest` are always non-null after construction.
- The `RaiseNotification` event subscription is established during construction and remains active for the lifetime of the ViewModel (no unsubscription is visible in the source).
- `IsDirty` can only be modified internally (private setter).
- The `_regionManager` field hides a base class member with the same name (via `new` keyword).
---
## 4. Dependencies
### This Module Depends On
| Namespace | Type(s) Used |
|-----------|--------------|
| `DTS.Common.Base` | `BaseViewModel<T>` |
| `DTS.Common.Events` | `RaiseNotification`, `NotificationContentEventArgs` |
| `DTS.Common.Interface` | `IViewModel`, `IDockPanelHorizontalViewModel` |
| `Microsoft.Practices.Prism.Events` | `IEventAggregator` |
| `Microsoft.Practices.Prism.Interactivity.InteractionRequest` | `InteractionRequest<T>`, `Notification`, `Confirmation` |
| `Microsoft.Practices.Prism.Regions` | `IRegionManager` |
| `Microsoft.Practices.Unity` | `IUnityContainer` |
### What Depends On This Module
Not determinable from source alone. The module implements `IDockPanelHorizontalViewModel`, suggesting consumers depend on that interface rather than the concrete class directly.
---
## 5. Gotchas
1. **Most lifecycle methods are unimplemented**: `Initialize()`, `Initialize(object)`, `Activated()`, `Cleanup()`, `CleanupAsync()`, `Initialize(object, object)`, `InitializeAsync()`, and `InitializeAsync(object)` all throw `NotImplementedException`. This class appears to be a partial implementation or stub.
2. **Method hiding with `new` keyword**: `CleanupAsync()` and `Initialize(object parameter, object model)` use `new` rather than `override`, potentially hiding base class implementations. This may indicate a design inconsistency or versioning artifact.
3. **Field hiding**: The `_regionManager` field is declared with `new`, hiding a base class member. The implications of this depend on the base class implementation.
4. **Redundant object construction in `OnRaiseNotification`**: The handler constructs a new `NotificationContentEventArgs` from the received one, passing `Message`, `MessageDetails`, and `Image` to the constructor. The comment indicates this is intentional ("expects a NotificationContentEventArgsWithoutTitle object"), but the type used is `NotificationContentEventArgs`. Whether this is correct or a bug is unclear from source alone.
5. **No event unsubscription**: There is no visible unsubscription from `RaiseNotification` in any cleanup method. Since `Cleanup()` throws `NotImplementedException`, memory leaks via event subscription are possible if the base class does not handle this.
6. **Unused `Parent` property**: The `Parent` property (type `IViewModel`) is declared but never assigned or used in the visible source.

View File

@@ -0,0 +1,54 @@
---
source_files:
- DTS Viewer/DTS.Viewer/View/DockPanelVertical/View/DockPanelVerticalView.xaml.cs
generated_at: "2026-04-16T11:25:25.151183+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "dd7d632d568da85b"
---
# Documentation: DockPanelVerticalView
## 1. Purpose
`DockPanelVerticalView` is a WPF view component that serves as the code-behind for a XAML-defined vertical dock panel user interface. It implements the `IDockPanelVerticalView` interface, enabling abstraction and likely facilitating dependency injection or MVVM pattern integration within the DTS Viewer application.
---
## 2. Public Interface
### Class: `DockPanelVerticalView`
**Namespace:** `DTS.Viewer`
**Implements:** `IDockPanelVerticalView`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `public DockPanelVerticalView()` | Initializes a new instance of the view and calls `InitializeComponent()` to load the associated XAML layout. |
---
## 3. Invariants
- `InitializeComponent()` must be called exactly once during construction for the XAML-defined UI elements to be instantiated.
- The class is `partial`, indicating it must be paired with a corresponding XAML file (`DockPanelVerticalView.xaml`) that defines the visual layout.
- The view must implement `IDockPanelVerticalView` to satisfy the interface contract (specific interface members are not visible in this source file).
---
## 4. Dependencies
### This module depends on:
- `DTS.Common.Base` — Imported but no types from this namespace are directly referenced in the visible source.
- `DTS.Common.Interface` — Provides the `IDockPanelVerticalView` interface that this class implements.
- **WPF infrastructure** — Implicit dependency on `System.Windows` (inferred from `InitializeComponent()` pattern and `.xaml.cs` file extension).
### What depends on this module:
- **Not determinable from source alone.** Consumers would typically be parent views, view composition logic, or an IoC container registering this view.
---
## 5. Gotchas
- **Base class not visible:** The source does not explicitly declare a base class. As a `partial` class paired with XAML, the base class is likely defined in the XAML root element (commonly `UserControl` or `Window`). The exact base type cannot be confirmed from this file alone.
- **Empty code-behind:** The class contains no additional logic beyond initialization. Any behavior (event handlers, data binding setup, etc.) is either in the XAML file, a associated ViewModel, or injected elsewhere.
- **Unused import:** `DTS.Common.Base` is imported but no types from it are referenced in the visible code. This may indicate legacy code, a removed feature, or types used only in the XAML portion.

View File

@@ -0,0 +1,103 @@
---
source_files:
- DTS Viewer/DTS.Viewer/View/DockPanelVertical/ViewModel/DockPanelVerticalViewModel.cs
generated_at: "2026-04-16T11:25:25.613899+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "0185c1c3d29b204b"
---
# DockPanelVerticalViewModel Documentation
## 1. Purpose
`DockPanelVerticalViewModel` is a ViewModel component for a vertical dock panel UI element within a WPF/Prism-based application. It serves as the data context for `IDockPanelVerticalView`, managing notification/confirmation dialogs and exposing panel configuration state flags. The class inherits from `BaseViewModel<IDockPanelVerticalViewModel>` and integrates with Prism's event aggregation and region management infrastructure.
---
## 2. Public Interface
### Constructor
```csharp
public DockPanelVerticalViewModel(
IDockPanelVerticalView view,
IRegionManager regionManager,
IEventAggregator eventAggregator,
IUnityContainer unityContainer)
```
Initializes the ViewModel, sets the View's DataContext to itself, creates interaction requests, and subscribes to the `RaiseNotification` event.
### Properties
| Property | Type | Access | Description |
|----------|------|--------|-------------|
| `View` | `IDockPanelVerticalView` | `get` | Reference to the associated view instance. |
| `NotificationRequest` | `InteractionRequest<Notification>` | `get` | Prism interaction request for displaying notifications. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | `get` | Prism interaction request for displaying confirmations. |
| `IsMenuIncluded` | `bool` | `get/set` | Flag indicating whether a menu is included in the panel. |
| `IsNavigationIncluded` | `bool` | `get/set` | Flag indicating whether navigation is included in the panel. |
| `IsBusy` | `bool` | `get/set` | Busy state indicator. |
| `IsDirty` | `bool` | `get` (private set) | Dirty state indicator; read-only externally. |
### Events
```csharp
public event PropertyChangedEventHandler PropertyChanged;
```
Declared but **never invoked** within this class.
### Methods
| Method | Return Type | Behavior |
|--------|-------------|----------|
| `Initialize()` | `void` | Throws `NotImplementedException`. |
| `Initialize(object parameter)` | `void` | Throws `NotImplementedException`. |
| `Initialize(object parameter, object model)` | `void` | Throws `NotImplementedException`. Uses `new` keyword. |
| `InitializeAsync()` | `Task` | Throws `NotImplementedException`. |
| `InitializeAsync(object parameter)` | `Task` | Throws `NotImplementedException`. |
| `Activated()` | `void` | Throws `NotImplementedException`. |
| `Cleanup()` | `void` | Throws `NotImplementedException`. |
| `CleanupAsync()` | `Task` | Throws `NotImplementedException`. Uses `new` keyword. |
---
## 3. Invariants
- **DataContext Binding**: The View's `DataContext` is always set to `this` ViewModel instance upon construction.
- **Event Subscription**: The ViewModel subscribes to `RaiseNotification` event during construction; the subscription lifetime is tied to the EventAggregator's scope.
- **Notification Transformation**: `OnRaiseNotification` transforms `NotificationContentEventArgs` (with title) into `NotificationContentEventArgs` (without title) plus a separate Title string when raising the notification request.
---
## 4. Dependencies
### This module depends on:
- `DTS.Common.Base``BaseViewModel<T>`
- `DTS.Common.Events``RaiseNotification` event, `NotificationContentEventArgs`
- `DTS.Common.Interface``IViewModel`, `IDockPanelVerticalViewModel`, `IDockPanelVerticalView`
- `Microsoft.Practices.Prism.Events``IEventAggregator`
- `Microsoft.Practices.Prism.Interactivity.InteractionRequest``InteractionRequest<T>`, `Notification`, `Confirmation`
- `Microsoft.Practices.Prism.Regions``IRegionManager`
- `Microsoft.Practices.Unity``IUnityContainer`
### What depends on this module:
- **Unclear from source alone** — No consumers are visible in this file. Likely consumed by View implementations and/or DI container registrations.
---
## 5. Gotchas
1. **Incomplete Implementation**: All lifecycle methods (`Initialize`, `InitializeAsync`, `Activated`, `Cleanup`, `CleanupAsync`) throw `NotImplementedException`. This class appears to be a stub or work-in-progress.
2. **Member Hiding**:
- The `_regionManager` field uses `new`, hiding a base class member of the same name.
- `CleanupAsync()` and `Initialize(object parameter, object model)` also use `new`, hiding base implementations rather than overriding them.
3. **Unused `PropertyChanged` Event**: The event is declared but never raised. If property change notification is expected by consumers, it will not function.
4. **Unused `ConfirmationRequest`**: The `ConfirmationRequest` property is instantiated but never raised anywhere in this class.
5. **Unused State Properties**: `IsMenuIncluded`, `IsNavigationIncluded`, `IsBusy`, and `IsDirty` are declared but never read or written within this class (other than being auto-initialized).
6. **Potential Memory Leak**: The `RaiseNotification` event subscription does not appear to be unsubscribed in cleanup (though cleanup throws anyway). If the EventAggregator uses weak references, this may be safe; otherwise, it could cause memory retention issues.

View File

@@ -0,0 +1,38 @@
---
source_files:
- DTS Viewer/DTS.Viewer/View/Navigation/View/NavigationView.xaml.cs
generated_at: "2026-04-16T11:25:05.068358+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "4b4942c6e8f5eadd"
---
# Documentation: NavigationView
## 1. Purpose
This module defines the code-behind class for the `NavigationView` component within the DTS Viewer application. It serves as a WPF User Control responsible for the visual presentation of navigation elements. Its primary role is to implement the `INavigationView` interface, bridging the gap between the XAML layout definition and the application's navigation logic.
## 2. Public Interface
### Class: `NavigationView`
**Inherits:** `INavigationView` (from `DTS.Common.Interface`)
**Type:** `partial` class
#### Constructor: `NavigationView()`
* **Signature:** `public NavigationView()`
* **Behavior:** Initializes the component. It calls the standard WPF `InitializeComponent()` method, which loads the associated XAML markup (`NavigationView.xaml`) required to render the view.
## 3. Invariants
* **WPF Initialization:** The `InitializeComponent()` method must be called exactly once upon instantiation to ensure the UI elements defined in XAML are created.
* **Interface Compliance:** As this class implements `INavigationView`, it must satisfy the contract defined in `DTS.Common.Interface.INavigationView`. (Note: The specific members of this interface are not visible in the provided source).
## 4. Dependencies
* **Imports:**
* `DTS.Common.Interface`: Used for the `INavigationView` interface.
* **Internal Dependencies:**
* `NavigationView.xaml`: This is a code-beind file; it relies on a corresponding XAML file to define the actual UI structure.
* Implicit WPF Assemblies: Relies on `System.Windows` (specifically `System.Windows.Controls.UserControl` behavior) for `InitializeComponent()`.
## 5. Gotchas
* **Missing Logic Implementation:** The source file contains no explicit implementation of the `INavigationView` interface members. It is unclear from this source alone whether the interface is a marker interface (empty) or if the implementation is expected elsewhere (e.g., via explicit interface implementation not shown, or if the file provided is incomplete).
* **XAML Dependency:** The functionality and visual behavior of this view are entirely dependent on the associated `NavigationView.xaml` file, which is not included here. The C# code acts purely as a bridge.

View File

@@ -0,0 +1,106 @@
---
source_files:
- DTS Viewer/DTS.Viewer/View/Navigation/ViewModel/NavigationViewModel.cs
generated_at: "2026-04-16T11:24:52.139730+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "a00beb6f74b53389"
---
# Documentation: NavigationViewModel
## 1. Purpose
`NavigationViewModel` is a Prism-based ViewModel responsible for managing the navigation region within the DTS Viewer application's shell. It serves as a mediator between the `INavigationView` and the application's navigation infrastructure, handling notification events via `IEventAggregator` and exposing a `ContextNavigationRegion` property for dynamically setting navigation content. This class inherits from `BaseViewModel<INavigationViewModel>` and implements the `INavigationViewModel` interface.
---
## 2. Public Interface
### Constructor
```csharp
public NavigationViewModel(INavigationView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
```
Initializes the view model with its associated view and Prism infrastructure dependencies. Sets the view's `DataContext` to itself, initializes interaction requests, and subscribes to the `RaiseNotification` event.
### Properties
| Property | Type | Access | Description |
|----------|------|--------|-------------|
| `NavigationView` | `INavigationView` | `get; private set;` | The associated navigation view instance. |
| `NotificationRequest` | `InteractionRequest<Notification>` | `get; private set;` | Interaction request for displaying notifications. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | `get; private set;` | Interaction request for displaying confirmations. |
| `ContextNavigationRegion` | `object` | `get; set;` | Gets or sets the content of the `NavigationRegion` on the underlying view. Raises `OnPropertyChanged` on set. |
| `HeaderInfo` | `string` | `get;` | Returns the constant string `"NavigationRegion"`. |
| `IsBusy` | `bool` | `get; set;` | **Throws `NotImplementedException`** in both getter and setter. |
| `IsDirty` | `bool` | `get;` | **Throws `NotImplementedException`** in getter. |
### Events
```csharp
public new event PropertyChangedEventHandler PropertyChanged;
```
Hides the base class event. Raised via the private `OnPropertyChanged(string propertyName)` method.
### Methods
| Method | Return Type | Description |
|--------|-------------|-------------|
| `Initialize()` | `void` | Empty override; performs no initialization. |
| `Initialize(object parameter)` | `void` | Sets the `Parent` property by casting `parameter` to `IShellViewModel`. |
| `Activated()` | `void` | **Throws `NotImplementedException`**. |
| `Cleanup()` | `void` | **Throws `NotImplementedException`**. |
| `CleanupAsync()` | `Task` | **Throws `NotImplementedException`**. |
| `InitializeAsync()` | `Task` | **Throws `NotImplementedException`**. |
| `InitializeAsync(object parameter)` | `Task` | **Throws `NotImplementedException`**. |
### Private Methods
```csharp
private void OnRaiseNotification(NotificationContentEventArgs eventArgsWithTitle)
```
Event handler for `RaiseNotification` events. Transforms `NotificationContentEventArgs` into a `NotificationContentEventArgs` (without title) and raises the `NotificationRequest` with separate content and title.
---
## 3. Invariants
- `NavigationView` is assigned in the constructor and never reassigned.
- `Parent` is only set via `Initialize(object parameter)` and must be castable to `IShellViewModel`.
- The `RaiseNotification` event subscription is established at construction time and remains active for the lifetime of the view model.
- `ContextNavigationRegion` assumes the underlying `NavigationView` can be cast to the concrete `NavigationView` type to access `NavigationRegion.Content`.
---
## 4. Dependencies
### This module depends on:
- `DTS.Common.Base` — Provides `BaseViewModel<T>`
- `DTS.Common.Events` — Provides `RaiseNotification` event and `NotificationContentEventArgs`
- `DTS.Common.Interface` — Provides `INavigationViewModel`, `INavigationView`, `IShellViewModel`
- `Microsoft.Practices.Prism.Events` — Provides `IEventAggregator`
- `Microsoft.Practices.Prism.Interactivity.InteractionRequest` — Provides `InteractionRequest<T>`, `Notification`, `Confirmation`
- `Microsoft.Practices.Prism.Regions` — Provides `IRegionManager`
- `Microsoft.Practices.Unity` — Provides `IUnityContainer`
### What depends on this module:
- Cannot be determined from source alone (no consumers visible in this file).
---
## 5. Gotchas
1. **Incomplete Implementation**: Multiple methods (`Activated`, `Cleanup`, `CleanupAsync`, `InitializeAsync`, `InitializeAsync(object parameter)`) and properties (`IsBusy`, `IsDirty`) throw `NotImplementedException`. This class appears to be partially implemented.
2. **Member Hiding**: The `new` keyword is used to hide base class members (`PropertyChanged`, `OnPropertyChanged`, `IsBusy`, `IsDirty`, `CleanupAsync`). This may indicate a design issue or conflict with the base `BaseViewModel<T>` implementation.
3. **Stale XML Documentation**: The constructor's XML comment states "Creates a new instance of the TechnologyDoFrontEditViewModel" — this appears to be a copy-paste error from another view model.
4. **Unsafe Cast in ContextNavigationRegion**: The property directly casts `INavigationView` to the concrete `NavigationView` type:
```csharp
((NavigationView)NavigationView).NavigationRegion.Content
```
This will throw an `InvalidCastException` at runtime if the injected view is not exactly of type `NavigationView`.
5. **Event Transformation Logic**: `OnRaiseNotification` creates a new `NotificationContentEventArgs` from the received event args, extracting `Message`, `MessageDetails`, and `Image` while separating `Title`. This transformation may lose data if additional properties exist on the source event args.

View File

@@ -0,0 +1,221 @@
---
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**: `