Files

111 lines
8.9 KiB
Markdown
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- DataPRO/Modules/Groups/GroupChannelList/ViewModel/GroupChannelListViewModel.cs
generated_at: "2026-04-17T16:01:14.282913+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "593e1e1e445f103d"
---
# GroupChannelListViewModel Documentation
## 1. Purpose
The `GroupChannelListViewModel` class serves as the presentation logic layer for managing channel configurations within Groups and Test Setups in a data acquisition system. It orchestrates the assignment of sensors and hardware channels, handles text parsing for bulk channel creation, manages filtering and sorting of channel lists, and coordinates UI interactions through Prism's event aggregation system. The class supports both Group-based channel management and Test Setup ordering modes, providing bidirectional synchronization between channel properties and underlying data models.
## 2. Public Interface
### Properties
| Signature | Description |
|-----------|-------------|
| `IGroupChannelListView View { get; set; }` | The associated view instance. |
| `IGroupChannelSettingsListView SettingsView { get; set; }` | The settings view instance. |
| `InteractionRequest<Notification> NotificationRequest { get; }` | Interaction request for displaying notifications. |
| `InteractionRequest<Confirmation> ConfirmationRequest { get; }` | Interaction request for displaying confirmations. |
| `bool SettingsViewLoaded { get; set; }` | Indicates whether the SettingsView has loaded. |
| `bool SettingChannelsLoaded { get; set; }` | Indicates whether SettingChannel UI elements were created. |
| `event PropertyChangedEventHandler PropertyChanged` | Property change notification event. |
### Methods
| Signature | Description |
|-----------|-------------|
| `void OnPropertyChanged(string propertyName)` | Raises `PropertyChanged` event; publishes `GroupChannelsChangedEvent` when `ChannelCount` changes. |
| `void UpdateRangeLowG(IGroupChannel channelChanged)` | Updates all Low G channels on the same DAS to match the range of the changed channel. |
| `void UpdateRangeARS(IGroupChannel channelChanged)` | Updates all ARS channels on the same DAS to match the range of the changed channel. |
| `void UpdateACCouplingEnabled(IGroupChannel channelChanged)` | Propagates AC coupling enabled state to other channels on the same DAS. |
| `IGroup CreateGroupIfNeeded(ITestSetup testSetup, string groupName)` | Creates a group if it doesn't exist; delegates to `GroupList.Model.Group.CreateGroupIfNeeded`. |
| `void DoSensorAssignment(IGroupChannel groupChannel, IDragAndDropItem[] sensors)` | Assigns sensors to channels starting at the specified channel index. Refuses assignment to TSR AIR channels (non-StreamOut/non-Uart). |
| `void DoHardwareAssignment(IGroupChannel groupChannel, IHardwareChannel[] hardwareChannels)` | Assigns hardware channels starting at the specified index. TSR AIR hardware has special restrictions. |
| `void Unset()` | Clears all channels, dictionaries, and filters; resets view state. |
| `void ClearAllFilters()` | Resets search term, bridge filter, and field filters; publishes `ListViewStatusEvent`. |
| `void OnSetActive()` | Refreshes channel state, column visibility, and UI bindings when the view becomes active. |
| `bool CompareAndMarkChannelParameters(IGroupChannel ch)` | Compares channel parameters against sensor database values; marks differences for UI decoration. |
| `IDictionary<IGroup, IGroupChannel[]> PopulateChannels(object page, IDictionary<int, ISensorData> sensorLookup, IDictionary<int, IDASHardware> hardwareLookup, IChannelSetting[] channelDefaults, bool allowChannelDeletionByNonAdminUser = true, bool userIsAdmin = true, bool allowSensorPushAndPull = false, bool keepExistingChannels = false, bool allowChannelDeletionFromFixedGroup = false)` | Populates channel lists from sensor and hardware lookups; handles TSR AIR embedded sensors and fixed group constraints. |
| `void Cleanup()` | Empty cleanup method. |
| `Task CleanupAsync()` | Returns `Task.CompletedTask`. |
| `void Initialize()`, `void Initialize(object parameter)`, `void Initialize(object parameter, object model)` | Empty initialization methods. |
| `Task InitializeAsync()`, `Task InitializeAsync(object parameter)` | Return `Task.CompletedTask`. |
| `void Activated()` | Empty activation method. |
| `void ReportErrors(string[] errors)` | Publishes `PageErrorEvent` with provided errors. |
| `void GroupNameChanged(IGroupChannel channel)` | Handles group name changes in Test Setup mode; removes channel from old group, creates new group if needed. |
| `void MarkModified(IGroupChannel channel, bool bNotifyChanged = true)` | Marks a channel as modified; adds a new blank channel if modifying the last one. |
| `void NotifyChannelsChanged()` | Publishes `PageModifiedEvent` and `GroupUpdatedEvent`; raises property change for counts. |
| `void Clear(IGroupChannel channel)` | Clears the specified channel's data. |
| `void Remove(IGroupChannel channel, bool notifyChanged = true)` | Removes a channel from the list; handles Test Setup group cleanup. |
## 3. Invariants
1. **Blank Channel at End**: `AllChannels` and `Channels` collections always contain a blank `GroupChannel` at the end, used for adding new channels via `MarkModified`.
2. **TSR AIR Channel Restrictions**: Channels with `HardwareChannel.IsTSRAIR == true` (excluding StreamOut and Uart types) cannot have sensors or hardware reassigned via drag-and-drop.
3. **Channel Ordering**: Channels maintain either `TestSetupOrder` or `GroupChannelOrder` (1-indexed), determined by `UseTestSetupOrder` property.
4. **ISO Code Length**: ISO codes are truncated to 16 characters maximum in `ParseText`.
5. **Move Button State**: The first channel has `CanMoveUp = false`; the last non-blank channel has `CanMoveDown = false`.
6. **Filter Preservation**: Channels in `_dontFilterList` are excluded from filtering operations to maintain visibility during editing.
7. **Fixed Group Deletion**: When `AllowChannelDeletionFromFixedGroup = false`, channels with non-null `StaticGroupId` have `DeleteShouldBeEnabled = false`.
## 4. Dependencies
### This Module Depends On:
- **Prism Framework**: `IEventAggregator`, `IRegionManager`, `Delegate` commands, `InteractionRequest`
- **Unity Container**: `IUnityContainer` for service resolution
- **DTS.Common.Classes.Groups**: `Group` model class
- **DTS.Common.Enums**: `HardwareTypes`, `PossibleFilters`, `Fields`, sensor enums
- **DTS.Common.Events**: `GroupChannelsChangedEvent`, `RaiseNotification`, `BusyIndicatorChangeNotification`, `TextPastedEvent`, `PageErrorEvent`, `PageModifiedEvent`, `GroupUpdatedEvent`, `AppStatusEvent`, `ListViewStatusEvent`
- **DTS.Common.Interface.Channels**: `IHardwareChannel`, `IChannelCode`, `IChannelSetting`
- **DTS.Common.Interface.Groups.GroupChannelList**: `IGroupChannelListView`, `IGroupChannelSettingsListView`, `IGroupChannel`
- **DTS.Common.Interface.Sensors**: `ISensorData`, `IDragAndDropItem`
- **DTS.Common.Storage**: `DbOperations` for channel setting defaults
- **DTS.Common.Constants**: `TDAS_TOM_DIGITAL_OUT_DURATION_MAX`
- **System.ComponentModel.Composition**: `[PartCreationPolicy(CreationPolicy.Shared)]` for MEF
### Events Consumed:
- `RaiseNotification``OnRaiseNotification`
- `BusyIndicatorChangeNotification``OnBusyIndicatorNotification`
- `TextPastedEvent``OnTextPasted`
### Events Published:
- `GroupChannelsChangedEvent`, `PageErrorEvent`, `PageModifiedEvent`, `GroupUpdatedEvent`, `AppStatusEvent`, `ListViewStatusEvent`
## 5. Gotchas
1. **TSR AIR Embedded Sensors**: The `PopulateChannels` method contains special logic to handle embedded sensors in TSR-AIR units, only adding them if the unit isn't already represented in the group. This logic is spread across multiple checks and can be difficult to follow.
2. **Sensor Serial Number Parsing**: `GetSensorSerialNumber` handles sensors with names in format `"Name (SerialNumber)"` vs. just `"SerialNumber"`. The dictionary lookup depends on this parsing being consistent.
3. **Blank Channel Management**: The blank channel at the end of lists is both a UI affordance and a state management mechanism. Removing or modifying it triggers creation of a new blank channel, which can cause unexpected list changes.
4. **Test Setup vs. Group Mode**: Many methods check `UseTestSetupOrder` to determine behavior. The same ViewModel serves both contexts, and some operations (like `GroupNameChanged`) are no-ops in Group mode.
5. **Filter State Persistence**: `_dontFilterList` is cleared on user-initiated filter operations but preserved during programmatic filtering. This can lead to unexpected channel visibility if not managed carefully.
6. **Digital Out Duration Max**: TDAS TOM hardware has a hardcoded max value (`TDAS_TOM_DIGITAL_OUT_DURATION_MAX`) applied in `ResetSettingChannels`, separate from other channel validation.
7. **Sensor Push/Pull**: The `AllowSensorPushAndPull` flag affects whether channel parameters are compared against sensor database values and whether `BorderShouldShowOutOfDate` is set. This feature appears to be for highlighting parameter drift from sensor defaults.