This module provides view models for managing hardware channel assignments in TTS (Test Technology Suite) import workflows, specifically for digital output (DO), digital input (DI), TOM (Twin Oscillator Module, i.e., squib channels), and level trigger configurations. Each view model acts as a bridge between the UI and the underlying test setup data (ITTSSetup), hardware scan results (IDASHardware), and sensor-to-channel mapping (EIDMappingEvent). They handle real-time updates via Prism events, support interactive channel assignment/removal/enable/disable operations, and maintain UI state such as busy indicators and selection states. The module exists to decouple UI logic from core test setup management and to provide a consistent, event-driven pattern for channel configuration across different channel types.
ObservableCollection<DASChannel> DASChannels { get; set; }
Collection of digital output channels discovered during hardware scan, with optional sensor assignments.
DASChannel SelectedDASChannel { get; set; }
Currently selected channel in the UI.
string EnableOrDisableText { get; }
UI text for the enable/disable button (e.g., “Enable” or “Disable”) based on channel state.
bool IsBusy { get; set; }
Indicates whether a background operation is in progress.
bool IsMenuIncluded, IsNavigationIncluded { get; set; }
UI layout flags (not used in logic).
void Cleanup(), Task CleanupAsync()
No-op stubs; no cleanup logic implemented.
void Initialize(...), Task InitializeAsync(...)
No-op stubs; initialization is handled via constructor event subscriptions.
void Activated()
No-op stub.
event PropertyChangedEventHandler PropertyChanged
Standard INotifyPropertyChanged implementation.
_setup and _hardware must be non-null before OnAssignedChannelsChangedEvent (or equivalent) logic executes; otherwise, the method returns early.
DASChannel instances are constructed with an IHardwareChannel and optionally an ITTSSetup (e.g., new DASChannel(ch, _setup) in DigitalOutputChannelsViewModel).
DASChannel.SetITTSChannelRecord(ITTSChannelRecord) is used to associate a hardware channel with a logical channel record; passing null removes the association.
DASChannel.EID is populated from _hardwareChannelIdToSensorId (or _sensorIdToChannelId in LevelTriggerViewModel) only if the hardware channel ID exists as a key.
IsBusy is updated only via OnBusyIndicatorNotification(bool), triggered by BusyIndicatorChangeNotification event.
IsMenuIncluded and IsNavigationIncluded are UI flags only; they do not affect business logic.
IsDirty is declared but never set; it remains false throughout the lifetime of the view model.
EnableOrDisableText is computed from SelectedDASChannel?.Channel?.Disabled and StringResources constants.
LevelTriggers is read-only and derived from _setup.LevelTriggers; no direct modification is performed in LevelTriggerViewModel.
TOMChannelsViewModel only processes hardware channels where ch.IsSquib is true, and iterates hardware channels in pairs (i += 2) to select squib channels.
DigitalInputChannelsViewModel and TOMChannelsViewModel share identical command logic (Assign, Remove, EnableOrDisable) and state management (DetermineRemoveEnableStatus).
DigitalOutputChannelsViewModel is used when configuring digital output channels after hardware scan and EID mapping.
DigitalInputChannelsViewModel and TOMChannelsViewModel are used for interactive assignment of unassigned channels to hardware, with similar UI patterns.
LevelTriggerViewModel is used for level trigger configuration and relies on TTSImportReadFileStatusEvent and TTSImportSavedChangesStatusEvent to trigger UpdateLevelTriggers().
All view models depend on AssignedChannelsChangedEvent to refresh channel lists when assignments change elsewhere in the system.
5. Gotchas
IsDirty is never set to true — it is declared but unused. Any change detection must be handled externally (e.g., via TTSImportTestSetupChangedEvent).
Cleanup() and Initialize() methods are no-ops — no resource cleanup or initialization logic is implemented in these methods.
LevelTriggers is read-only — LevelTriggerViewModel does not support creating or deleting level triggers; it only exposes existing ones.
TOMChannelsViewModel assumes squib channels are paired — it iterates hardware channels in steps of 2 (i += 2) to select squib channels, which may not hold if hardware layout changes.
DigitalInputChannelsViewModel and TOMChannelsViewModel use SelectedRemainingChannel and SelectedDASChannel to control button states, but selection changes may not trigger DetermineRemoveEnableStatus() if not handled via property setters (e.g., programmatic selection may require manual OnPropertyChanged).
AssignWork() in DigitalInputChannelsViewModel and TOMChannelsViewModel modifies RemainingChannels and DASChannels collections directly, which may cause UI flicker or require CollectionViewSource.GetDefaultView(...).Refresh() to update.
OnAssignedChannelsChangedEvent in DigitalOutputChannelsViewModel creates new TTSChannelRecord instances for unassigned channels, but does not add them to _setup.Channels — only the DASChannel is updated. This may lead to inconsistencies if _setup.Channels is expected to be authoritative.
OnEIDComplete in DigitalOutputChannelsViewModel inverts the sensor-to-channel mapping, but only if the input dictionary is non-empty. If empty, _hardwareChannelIdToSensorId remains an empty dictionary.
VoltageIsValid in LevelTriggerViewModel catches all exceptions from GetExcitationVoltageEnumFromMagnitude, which may hide invalid voltage inputs (e.g., negative or unsupported values).
DigitalInputChannelsViewModel and TOMChannelsViewModel use MessageBox.Show for confirmation prompts, which is synchronous and may block the UI thread. The use of Task.Run around MessageBox.Show is unnecessary and misleading (UI calls must be on the UI thread).
EnableOrDisableText uses StringResources.Analog_Enable and StringResources.Analog_Disable — misleading naming for digital channels.
DASChannel.EID is only set if the hardware channel ID exists in _hardwareChannelIdToSensorId — if the mapping is incomplete, EID may be missing even if a sensor is physically present.
No validation is performed on SelectedDASChannel or SelectedRemainingChannel before assignment — null checks are present in command handlers but not in property setters.
LevelTriggerViewModel does not expose DASChannels or RemainingChannels — it only exposes LevelTriggers, making it impossible to view or edit channel assignments directly in this view model.