Files
2026-04-17 14:55:32 -04:00

222 lines
10 KiB
Markdown

---
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<IRegionOfInterest>`.
**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<IRegionOfInterest>` | Collection of ROIs; setter scrubs invalid channel references. |
| `AllChannelsUnfiltered` | `List<GroupChannel>` | All channels before filtering. |
| `AllChannels` | `ObservableCollection<GroupChannel>` | Channels displayed in UI (filtered). |
| `AllChannelSSNs` | `string[]` | Array of hardware\serialNumber strings for all channels. |
| `ChannelList` | `BindingList<ChannelEnabler>` | Grid data source with ROI checkbox states. |
| `Columns` | `ObservableCollection<ColumnDescriptor>` | Dynamic column definitions for grid. |
| `NotificationRequest` | `InteractionRequest<Notification>` | Prism interaction request for notifications. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | 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<string, IDASHardware> 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<string> 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<State>` | 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<ChannelEnabler>)
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 (`<name>_<index>_<uniqueId>` 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<T>`, `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.