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,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.