--- source_files: - DataPRO/Modules/RegionOfInterest/RegionOfInterestChannels/ViewModel/RegionOfInterestChannelsViewModel.cs generated_at: "2026-04-17T16:01:10.834469+00:00" model: "zai-org/GLM-5-FP8" schema_version: 1 sha256: "d3277795540da0ac" --- # RegionOfInterestChannelsViewModel Documentation ## 1. Purpose This module provides a ViewModel for managing Region of Interest (ROI) channel selections within a data acquisition/testing system. It handles the display, filtering, sorting, and selection of channels that can be associated with multiple regions of interest. The ViewModel supports two distinct data sources: live test setups (via `SetGroups`) and recorded test data (via `SetTest`), presenting channels in a configurable grid with ROI-specific checkbox columns for channel inclusion. ## 2. Public Interface ### RegionOfInterestChannelsViewModel (implements IRegionOfInterestChannelsViewModel) **Constructor:** ```csharp public RegionOfInterestChannelsViewModel( IRegionOfInterestChannelsView view, Prism.Regions.IRegionManager regionManager, Prism.Events.IEventAggregator eventAggregator, Unity.IUnityContainer unityContainer) ``` Initializes the ViewModel, wires up view DataContext, creates interaction requests, subscribes to `RaiseNotification` and `BusyIndicatorChangeNotification` events, and initializes `RegionsOfInterest` as an empty `BindingList`. **Properties:** | Property | Type | Description | |----------|------|-------------| | `IsDirty` | `bool` | Indicates unsaved changes (private setter). | | `IsBusy` | `bool` | Controls busy indicator state. | | `IsMenuIncluded` | `bool` | Menu inclusion flag. | | `IsNavigationIncluded` | `bool` | Navigation inclusion flag. | | `View` | `IRegionOfInterestChannelsView` | Associated view instance. | | `RegionsOfInterest` | `BindingList` | Collection of ROIs; setter scrubs invalid channel references. | | `AllChannelsUnfiltered` | `List` | All channels before filtering. | | `AllChannels` | `ObservableCollection` | Channels displayed in UI (filtered). | | `AllChannelSSNs` | `string[]` | Array of hardware\serialNumber strings for all channels. | | `ChannelList` | `BindingList` | Grid data source with ROI checkbox states. | | `Columns` | `ObservableCollection` | Dynamic column definitions for grid. | | `NotificationRequest` | `InteractionRequest` | Prism interaction request for notifications. | | `ConfirmationRequest` | `InteractionRequest` | Prism interaction request for confirmations. | | `ISOViewMode` | `IsoViewMode` | Controls which channel naming convention to display. | **Methods:** ```csharp public void SetParent(object o) ``` Stores a parent object reference for event publishing context. ```csharp public void SetTest(string path, IsoViewMode viewMode) ``` Loads test data from file path for export/viewing scenarios. Populates `_testSummary` and builds channel list from `ITestChannel` objects. ```csharp public void SetGroups(ITestSetup testSetup, Dictionary serialNumberToHardware, IsoViewMode viewMode) ``` Primary initialization for test setup scenarios. Processes groups, channels, and hardware assignments. Detects and reports phantom DAS channel assignments. ```csharp public void Filter(string term) ``` Sets search term and applies filtering. ```csharp public void SetFilter(PossibleFilters bridgeFilter) ``` Sets bridge filter type and applies filtering. ```csharp public void Filter(object tag, string term) ``` Sets field-specific filter (tag parsed as `Fields` enum) and applies filtering. ```csharp public void ClearAllFilters() ``` Clears all field-based filters. ```csharp public void Sort(object o, bool bColumnClick) ``` Sorts `ChannelList` by specified field. Toggles ascending/descending on repeated column clicks. ```csharp public void SelectAll(int roiIndex, bool selection) ``` Sets all channel checkboxes for a specific ROI index to the given selection state. ```csharp public bool Validate(ref List errors) ``` Returns `true` (no validation implemented). **Events:** - `PropertyChanged` - Standard `INotifyPropertyChanged` implementation. --- ### ChannelEnabler (public sealed, implements INotifyPropertyChanged) Represents a single row in the channel grid with ROI inclusion states. **Properties:** | Property | Type | Description | |----------|------|-------------| | `LastIndexChanged` | `int` | Index of last changed ROI checkbox. | | `ROIIncludes` | `BindingList` | Checkbox states per ROI. | | `UserCode`, `UserChannelName`, `ChannelName` | `string` | User-defined channel identifiers. | | `GuidString` | `string` | Unique identifier for this row. | | `ChannelId` | `long` | Numeric channel ID. | | `ISOCode`, `ISOChannelName` | `string` | ISO standard identifiers. | | `Hardware`, `SerialNumber`, `SensorName` | `string` | Hardware/sensor info. | | `DASSerialNumber`, `SampleRate`, `DisplayUnits` | `string` | DAS and measurement info. | | `Code`, `GroupName` | `string` | Additional identifiers. | **Methods:** ```csharp public string GetChannelName(IsoViewMode isoViewMode) ``` Returns appropriate channel name based on `IsoViewMode`. --- ### State (public sealed, implements INotifyPropertyChanged) Boolean checkbox state wrapper. **Constructor:** `public State(bool c)` **Properties:** - `Checked` (bool) - Checkbox state. **Methods:** - `public void Toggle()` - Inverts `Checked`. --- ### ROIChannelEnabler (public sealed, implements INotifyPropertyChanged) **Constructor:** `public ROIChannelEnabler(string suffix, string channel, bool enabled)` **Properties:** `ROISuffix`, `ChannelName`, `IsEnabled` (all string/bool with change notification). --- ### ColumnDescriptor (public sealed) **Properties:** `HeaderText` (string), `DisplayMember` (string), `MemberType` (Type). --- ### Fields (public enum) Values: `ChannelName`, `DisplayName`, `SerialNumber`, `SensorName`, `DASSerialNumber`, `SampleRate`, `ISOCode`, `DisplayUnits`, `GroupName`, `ROIIncludes`. --- ### ChannelEnablerComparer (sealed, IComparer) Internal comparer for sorting `ChannelEnabler` instances by any `Fields` value via reflection. ## 3. Invariants 1. **Channel ID Format Compatibility:** `ParseChannelId` must handle both legacy format (`__` or GUID-based) and current format (numeric only). Returns `-1` on parse failure. 2. **Channel Exclusion Rules:** Channels with `IsDisabled == true` or `SensorId < 0` are always excluded from processing and display. 3. **Digital Output Exclusion:** Channels with `IsDigitalOutput()` or `IsTestSpecificDigitalOutput` are scrubbed from ROI lists (FB14896). 4. **ROI-Channel Synchronization:** `ChannelEnabler.ROIIncludes` count must equal `_regionsOfInterest.Count`. Each index corresponds to the ROI at that index. 5. **Event Handler Lifecycle:** `ChannelList` setter detaches previous list's `ListChanged` handler before attaching to new list. 6. **Column Generation Order:** Columns are generated in fixed order: Group Name → User/ISO codes (based on `ISOViewMode`) → Hardware → Serial Number → Sensor Name → DAS Serial Number → Sample Rate → Display Units → ROI columns (dynamic). ## 4. Dependencies **External Dependencies (from imports and usage):** - `Prism.Regions.IRegionManager` - Region management for view composition - `Prism.Events.IEventAggregator` - Event pub/sub for decoupled communication - `Unity.IUnityContainer` - Dependency injection container - `DTS.Common.Classes.Groups.GroupChannel` - Channel data model - `DTS.Common.Enums.IsoViewMode` - Channel naming mode enum - `DTS.Common.Enums.Sensors` / `DTS.Common.Enums.Hardware` - Enumeration types - `DTS.Common.Events.RaiseNotification`, `BusyIndicatorChangeNotification`, `RegionOfInterestChannelsSelectedEvent`, `PageErrorEvent` - Event types - `DTS.Common.Interface.*` - Various interfaces (channels, groups, ROI, test definition) - `DTS.Common.Interactivity` - `InteractionRequest`, `Notification`, `Confirmation` - `DTS.SensorDB.SensorsCollection`, `DTS.SensorDB.SensorCalibrationList` - Sensor database access - `DTS.Common.Classes.Viewer.TestMetadata.TestMetadataList` - Test metadata loading - `DTS.Serialization.SliceRaw.File.PersistentChannel` - Channel persistence **Dependents (inferred):** - `IRegionOfInterestChannelsView` - The associated view - Components publishing `RaiseNotification` and `BusyIndicatorChangeNotification` events - Components subscribing to `RegionOfInterestChannelsSelectedEvent` ## 5. Gotchas 1. **Null `AllChannels` from Export Tile (13477):** When accessed from the export tile, `AllChannels` can be null. The `AllChannelSSNs` getter checks for this and falls back to `AllTestChannels`. 2. **Null `SensorData` in Download Route (18349):** In the download data route, `SensorData` can be null. Accessing it throws an exception. Code checks `if (null != ach.SensorData)` before access. 3. **Legacy ChannelId Parsing (44068):** Older `.dts` files have ChannelId formats like `"H3-3ch_0_2"` or `"f9f0bfe8-afc4-4730-8045-8f1e45340573_0_8533"`. Current format is just the unique number. `ParseChannelId` handles both. 4. **Channel Name Scrubbing (FB16120):** The `RegionsOfInterest` setter scrubs channel names not found in `AllChannelsUnfiltered` to handle bad/corrupt data. 5. **Embedded Channel Hardware Resolution:** Channels with `IsTestSpecificEmbedded` require special hardware resolution via `TestTemplateBase.GetEmbeddedChannelHardware()` rather than using `ch.Hardware` directly. 6. **"Assigned by ID" Prefix Stripping:** Hardware strings may have a leading "Assigned by ID" prefix that must be stripped via `RegionOfInterest.RemoveAssignedByIDFromHardwareString()`. 7. **Phantom DAS Assignment Detection:** `SetGroups` detects channels with `DASId > 0` but `DASChannelIndex < 0` and publishes a `PageErrorEvent` with `StringResources.PhantomDASChannelAssignment`. 8. **Sort Toggle Behavior:** When sorting, if the list is already in the target order (detected via `SequenceEqual`), the sort direction is automatically flipped for the user. 9. **Calibration Caching (FB18875):** Sensor calibrations are cached via `GetLatestCalibrations()` for performance, but are noted as not needed for ROI view. 10. **CURRENT_SUFFIX Handling:** `ParseChannelId` strips `DTS.Common.Constants.CURRENT_SUFFIX` from channel IDs before parsing.