--- source_files: - Common/DTS.Common.DataModel/Classes/TestObject/TemplateChannelUI.cs - Common/DTS.Common.DataModel/Classes/TestObject/TestObjectTemplateCollection.cs - Common/DTS.Common.DataModel/Classes/TestObject/TestObjectList.cs - Common/DTS.Common.DataModel/Classes/TestObject/TestTestObject.cs - Common/DTS.Common.DataModel/Classes/TestObject/TestObjectTemplate.cs generated_at: "2026-04-16T03:34:52.105415+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "600a818df3b392d9" --- # Documentation: DataModel.TestObject Module ## 1. Purpose This module provides data model abstractions for ISO 13499-compliant test objects, templates, and related UI wrappers within the DataPROWin7 application. It serves as the bridge between low-level ISO database entities (`DTS.Common.ISO.*`) and high-level WPF UI components, enabling template management, test object instantiation, and channel configuration. The module supports both system-built and user-defined templates, embedded vs. external template references, and test-specific overrides (e.g., excitation settings, position assignments). It is central to test setup definition, serialization, and runtime configuration. ## 2. Public Interface ### `TemplateChannelUI` - **`TemplateChannelUI(DTS.Common.ISO.TestObjectTemplateChannel channel)`** Constructor that wraps an ISO `TestObjectTemplateChannel` instance. Stores the channel in the `Channel` property. - **`Channel` (property)** Gets/sets the underlying `DTS.Common.ISO.TestObjectTemplateChannel`. Implements `INotifyPropertyChanged` via `BasePropertyChanged`. ### `TestObjectTemplateCollection` - **`TemplateCollection` (static property)** Singleton accessor. Returns the single instance of `TestObjectTemplateCollection`, lazily initialized. - **`SysBuiltTestObjectTemplate` (property)** Returns the read-only system-built template (note: `_sysBuiltTestObjectTemplate` is declared but *never initialized* in the source — likely incomplete). - **`GetTemplate(string templateId)` (method)** Retrieves a `TestObjectTemplate` by `templateId` from the ISO database (`ApplicationProperties.IsoDb`). Returns `null` if not found. ### `TestObjectList` - **`TestObjectsList` (static property)** Singleton accessor. Thread-safe (uses `lock(MyLock)`). Returns the single instance of `TestObjectList`. - **`Add(TestObject to, bool bNotify)` (method)** Adds a `TestObject` to the list. Sets `LastModifiedBy` and `LastModified` on the object, calls `Commit()`, and optionally raises `OnPropertyChanged("TestObjects")` if `bNotify` is `true`. - **`UpdateAll()` (method)** Raises `OnPropertyChanged("TestObjects")` to notify UI of changes (e.g., after bulk operations). ### `TestTestObject` - **Constructors** - `TestTestObject(TestObject obj)` Base constructor wrapping a `TestObject`. - `TestTestObject(TestTestObject obj, bool convertToEmbedded)` Copy constructor with support for converting to embedded mode (generates new GUIDs for template and serial number). - `TestTestObject(TestObject obj, bool convertToEmbedded)` Constructor for non-`TestTestObject` inputs with embedded conversion support. - `TestTestObject(TestTestObject to)` Copy constructor for metadata (calls `MetaCommonConstructor`). - **Properties** - `Position` (`DTS.Common.ISO.MMEPositions`) Gets/sets the group position. When set to `UserSetKey` (`"@"`), UI shows a button instead of a combo box. When set to a standard position, propagates the position to all required channels’ sensors. - `TestObject` (`DTS.Common.ISO.MMETestObjects`) Gets/sets the test object type. When set, propagates the test object to all required channels’ sensors. - `GroupPositionComboBoxVisible`, `GroupPositionButtonVisible` (`Visibility`) Controls UI visibility based on `Position` value. *Note: Non-ISO mode support is commented out.* - `AvailableGroupPositions` (`MMEPositions[]`) Returns an array containing `_channelDefaultsGUID` (`#`) and all positions from `ApplicationProperties.IsoDb.GetPositions()`. - `AvailablePositions` (`MMEPositions[]`) Returns positions from `ApplicationProperties.IsoDb.GetPositions()`. - `ChannelTypes` (`string[]`) Returns `["(no channels)"]` + unique channel types from `ApplicationProperties.IsoDb`. - `AddedGroups` (`TestObject[]`) Gets/sets a list of added system-built test objects; raises `OnPropertyChanged("AddedSysBuiltTestObjects")` and `OnPropertyChanged("AddedSysBuiltTestObjectsMME")`. - `DisplayOrder`, `IsAdd`, `SysBuilt`, `SerialNumberConverted` Metadata properties (no explicit backing fields beyond `DisplayOrder` and `IsAdd`). - `ExcitationWarmupTimeMS`, `TargetSampleRate`, `PreTriggerSeconds`, `PostTriggerSeconds` Test-specific configuration properties. - **Methods** - `Rename(string oldName, string newName)` Updates `SerialNumber`, `OriginalSerialNumber`, `OriginalTemplate`, `TestSetupName`, and generates new GUIDs for `TemplateName` and `OriginalTemplateName`. - `SetTestObject(string s)`, `SetPosition(string s)` Low-level setters that bypass property change notifications for `Position`/`TestObject` UI visibility logic. - `CompareTo(TestTestObject other)` Compares by `DisplayOrder`, then falls back to base comparison. ### `TestObjectTemplate` - **Constructors** - `TestObjectTemplate()` Default constructor; initializes with empty strings and first available test object. - `TestObjectTemplate(TestObjectTemplate copy, ref ISO13499FileDb db)` Deep copy constructor. - `TestObjectTemplate(DTS.Common.ISO.TestObjectTemplate template, ref ISO13499FileDb db)` Wraps an ISO template. - `TestObjectTemplate(DTS.Common.ISO.TestObjectTemplate template, ref ISO13499FileDb db, List testObjects)` Wraps an ISO template, preferring a provided list of `MMETestObjects`. - **Properties** - `TemplateName`, `TemplateDescription`, `LastModified`, `LastModifiedBy`, `TemplateParent`, `SysBuilt`, `IsLocalOnly`, `Embedded`, `OriginalTemplateName` Standard metadata properties. `Embedded` and `OriginalTemplateName` synchronize with the underlying `_template` object. - `TestObject` (`MMETestObjects`), `TestObjectType` (`string`) Gets/sets test object and type. Setting `TestObjectType` triggers channel list regeneration and order assignment. - `RequiredChannels` (`List`) List of required channels (not auto-populated; must be set explicitly). - `TemplateAllChannels` (`TestObjectTemplateChannel[]`), `TemplateAllUIChannels` (`TemplateChannelUI[]`) Arrays of all channels. `TemplateAllChannels` stores the raw ISO channels; `TemplateAllUIChannels` wraps them in `TemplateChannelUI` for UI binding. - `AvailableTestObjectTypes` (`string[]`) Derived from `TestObject` via `ApplicationProperties.IsoDb.GetTestObjectTypeForTestObject(...)`. - `TestObjectTypeIndex` (`int`) Index into `AvailableTestObjectTypes`; setting it updates `TestObjectType`. - **Methods** - `AssignOrders()` Sorts `TemplateAllChannels` and assigns `DisplayOrder` to channels with `-1`. - `ToISOTestObjectTemplate()` Converts to a standalone `DTS.Common.ISO.TestObjectTemplate` (for persistence/export). - `MarkChanged(string tag)` Raises `OnPropertyChanged(tag)`. - `CompareTo(TestObjectTemplate rhs)` Compares by `TemplateName` (ordinal). - `ReadXML(XmlElement root, Dictionary importChannels)` (static) Deserializes an ISO template from XML. Delegates to `ProcessXMLElement` and `ProcessChannelXMLNode`. - `ProcessXMLElement`, `ProcessChannelXMLNode` (private static) XML parsing helpers. `ProcessChannelXMLNode` handles channel-specific fields (e.g., `Required`, `DisplayOrder`, `LocalOnly`, `NameOfTheChannel`). ## 3. Invariants - **Singleton Consistency**: `TestObjectTemplateCollection.TemplateCollection` and `TestObjectList.TestObjectsList` are singletons. `TestObjectsList` uses explicit locking for thread safety; `TemplateCollection` does not (potential race condition on first access). - **Template Identity**: `TestObjectTemplate.TemplateName` and `OriginalTemplateName` must be non-null. `Embedded` templates use `OriginalTemplateName` for display (`ToString()` override). - **Channel Ordering**: `TestObjectTemplate.AssignOrders()` ensures `DisplayOrder` is non-decreasing and ≥ 0 for all channels after assignment. - **Position Propagation**: Setting `TestTestObject.Position` to a non-`UserSetKey` value propagates the position to all required channels’ sensors via `SetSensor(...)`. - **Test Object Propagation**: Setting `TestTestObject.TestObject` propagates the test object to all required channels’ sensors. - **XML Field Validation**: `ProcessChannelXMLNode` requires `MMEChannelId` and `MMEChannelType` to be present and parseable; otherwise, the channel is skipped. - **Metadata Copying**: `TestTestObject` copy constructors call `MetaCommonConstructor` to ensure test-specific metadata (e.g., `ExcitationWarmupTimeMS`, `Position`) is preserved. ## 4. Dependencies ### Internal Dependencies - **Base Classes**: `BasePropertyChanged` (for `INotifyPropertyChanged` implementation). - **ISO Layer**: `DTS.Common.ISO.TestObjectTemplate`, `TestObjectTemplateChannel`, `MMEPositions`, `MMETestObjects`, `MMEPossibleChannels`, `ISO13499FileDb`. - **Application Context**: `ApplicationProperties.IsoDb` (central database access), `ApplicationProperties.CurrentUser` (for `LastModifiedBy`). - **WPF**: `System.Windows.Visibility` (for UI state). ### External Dependencies - **Logging**: `DTS.Common.Utilities.Logging` (imported but no usage observed in source). - **DataModel**: `DTS.Common.DataModel` (namespace for shared types). - **Utilities**: `System`, `System.Collections.Generic`, `System.Linq`, `System.Xml`. ### Usage by Other Modules - `TestObjectTemplateCollection` is used to retrieve templates by ID (e.g., during test setup loading). - `TestObjectList` is used to manage test objects in a list (e.g., during test execution). - `TestTestObject` is used for test-specific test objects with override capabilities. - `TemplateChannelUI` is used in UI bindings for template channel properties. ## 5. Gotchas - **Uninitialized `SysBuiltTestObjectTemplate`**: `_sysBuiltTestObjectTemplate` is declared but never assigned in `TestObjectTemplateCollection`. Accessing `SysBuiltTestObjectTemplate` will return `null`. - **Thread Safety Gap**: `TestObjectTemplateCollection.TemplateCollection` is not thread-safe on first access (no locking), while `TestObjectList.TestObjectsList` is. - **Non-ISO Mode Code Commented Out**: `GroupPositionComboBoxVisible` and `GroupPositionButtonVisible` getters contain commented-out logic for `NO_ISO` mode. This may cause unexpected UI behavior if non-ISO mode is active. - **Channel Display Order Logic**: `AssignOrders()` and `ProcessChannelXMLNode` both assign `DisplayOrder` to `-1` channels, but `AssignOrders()` uses the *current* max + 1, while `ProcessChannelXMLNode` uses the *newly added* channel’s max + 1. This can lead to inconsistent ordering if channels are added incrementally. - **Template Name Overwrite in `Rename`**: `Rename` replaces `TemplateName` and `OriginalTemplateName` with new GUIDs, but does not update `TemplateParent`. This may break template hierarchy references. - **`TestObjectTemplateChannel` Duplication**: `TemplateAllChannels` and `TemplateAllUIChannels` store overlapping data. `TemplateAllChannels` is derived from `_allUIChannels`, but setting one does not automatically sync the other (e.g., `TemplateAllChannels` setter calls `TemplateAllUIChannels = ...`, but not vice versa). - **`TestTestObject` Constructor Overload Ambiguity**: Two constructors accept `(TestObject obj, bool convertToEmbedded)`. One is for `TestTestObject`, the other for `TestObject`. This may cause confusion or unintended behavior if misused. - **`_userSetGUID` and `_channelDefaultsGUID`**: These static `MMEPositions` instances are created with `Guid.NewGuid()` at type initialization. If multiple app domains or test runs occur, GUIDs may collide or behave unexpectedly (though unlikely in practice). - **`ToISOTestObjectTemplate` Omits Fields**: The method does not copy `Version`, `CRC32`, or `Icon` to the resulting ISO template, even though these are part of `GroupTemplateFields`. - **`ProcessChannelXMLNode` Ignores Many Fields**: Several `GroupTemplateChannelFields` (e.g., `BitResolution`, `ChannelAmplitudeClass`, `Comments`) are parsed but not applied to the channel. This may lead to data loss during XML import.