93 lines
7.8 KiB
Markdown
93 lines
7.8 KiB
Markdown
---
|
|
source_files:
|
|
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/ViewModel/GraphMainViewModel.cs
|
|
generated_at: "2026-04-16T11:10:28.732851+00:00"
|
|
model: "zai-org/GLM-5-FP8"
|
|
schema_version: 1
|
|
sha256: "09077834bf97663d"
|
|
---
|
|
|
|
# Documentation: GraphMainViewModel.cs
|
|
|
|
## 1. Purpose
|
|
The `GraphMainViewModel` class acts as the presentation logic controller for the Graph List module within the DTS Viewer application. It is responsible for managing the lifecycle of test channels—retrieving them from test summaries, organizing them into a hierarchical tree structure (Test > Group > Channel), and handling user interactions for selecting or locking channels for visualization. It serves as a bridge between the data layer (test summaries, metadata) and the UI layer, publishing events to notify other parts of the system when channels are selected, locked, or cleared.
|
|
|
|
## 2. Public Interface
|
|
|
|
### Public Properties
|
|
* **`IFilterView FilterView`**: Gets the filter view instance associated with this ViewModel.
|
|
* **`IGraphMainView View`**: Gets or sets the associated view interface.
|
|
* **`IBaseViewModel Parent`**: Gets or sets the parent ViewModel (used to scope events and behavior).
|
|
* **`InteractionRequest<Notification> NotificationRequest`**: Used to raise notification dialogs.
|
|
* **`InteractionRequest<Confirmation> ConfirmationRequest`**: Used to raise confirmation dialogs (hides base member).
|
|
* **`List<ITestChannel> LockedChannelList`**: Gets or sets the list of channels currently locked by the user.
|
|
* **`List<ITestChannel> SelectedChannelList`**: Gets or sets the list of channels currently selected by the user.
|
|
* **`ObservableCollection<ITestChannel> ChannelList`**: The master list of all available channels.
|
|
* **`ObservableCollection<ITestChannel> FilteredChannelList`**: The list of channels displayed to the user after filtering is applied.
|
|
* **`ObservableCollection<TreeViewChannels> TestChannelsTree`**: The hierarchical structure of channels bound to the UI TreeView.
|
|
* **`bool IsFilterEnabled`**: Indicates if the filter UI should be enabled (true if `ChannelList` has items).
|
|
* **`string SelectedGroupName`**: The name of the currently selected group.
|
|
* **`string LockedGroupName`**: The name of the currently locked group.
|
|
* **`bool TestModified`**: Indicates if the underlying test data has been modified.
|
|
|
|
### Public Methods
|
|
* **`void Initialize()`**: Overrides base method; currently empty.
|
|
* **`void Initialize(object parameter)`**: Initializes the ViewModel, sets the `Parent`, determines if locked-only mode is active (if Parent is `IPSDReportMainViewModel`), initializes the filter view, and subscribes to events.
|
|
* **`void PublishSelectedChannels()`**: Publishes the `GraphSelectedChannelsNotification` and `GraphSelectedChannelCountNotification` events containing the current lists of locked and/or selected channels.
|
|
* **`void AddLockedGroupChannels(string testName, string groupName, List<ITestChannel> channels, bool isLocked)`**: Adds or removes a group of channels to/from the `LockedChannelList`.
|
|
* **`void AddLockedChannel(ITestChannel channel, bool isLocked)`**: Adds or removes a single channel to/from the `LockedChannelList`.
|
|
* **`void AddSelectedGroupChannels(string groupName, List<ITestChannel> channels)`**: Selects a specific group of channels, resetting previous selections.
|
|
* **`void AddSelectedGroup(TestGroup group)`**: Marks a specific `TestGroup` as selected.
|
|
* **`void AddSelectedChannel(ITestChannel channel, bool reset)`**: Adds a single channel to the `SelectedChannelList`. If `reset` is true, previous selections are cleared.
|
|
* **`void AddSelectedChannel(ITestChannel channel)`**: Overload that resets previous selections before adding the new channel.
|
|
* **`void OnFilterChanged(FilterParameterArgs args)`**: Filters the `ChannelList` based on a string parameter and updates `FilteredChannelList`.
|
|
* **`void Activated()`**: Overrides base method; publishes an empty `FilterParameterChangedEvent` to reset the filter.
|
|
|
|
## 3. Invariants
|
|
|
|
* **Maximum Locked Channels**: The system enforces a hard limit of **8** locked channels (`MAX_LOCKED_CHANNELS`). The `UpdateChannelLocks` method disables the ability to lock further channels once this limit is reached.
|
|
* **Mutual Exclusivity**: A channel cannot be simultaneously in the `SelectedChannelList` and `LockedChannelList`. Locking a channel removes it from the selected list.
|
|
* **Color Assignment**: Channels are assigned colors from a fixed palette (`_graphColors`). The `GetNextColor` method ensures colors are unique if available, or cycles through the palette if the channel count exceeds the color count.
|
|
* **Parent Scoping**: Event handlers (e.g., `OnTestSummaryChanged`) check if the event's `ParentVM` matches the ViewModel's `Parent` property to ensure the event is relevant to this specific instance.
|
|
* **Locked-Only Mode**: If the `Parent` is of type `IPSDReportMainViewModel`, the `_lockedOnly` flag is set to `true`. In this mode, `PublishSelectedChannels` only publishes locked channels, ignoring selected channels.
|
|
|
|
## 4. Dependencies
|
|
|
|
### External Dependencies
|
|
* **Prism**: `IEventAggregator`, `IRegionManager` (for event pub/sub and region navigation).
|
|
* **Unity**: `IUnityContainer` (for dependency resolution).
|
|
* **System.Windows.Media**: `Color`, `Colors` (for channel visualization).
|
|
|
|
### Internal Dependencies (Inferred)
|
|
* **DTS.Common.Interface**: `ITestChannel`, `ITestSummary`, `IGraphMainView`, `IFilterView`, `ITestModificationModel`.
|
|
* **DTS.Common.Events**: `TestSummaryChangeNotificationArg`, `GraphClearNotificationArg`, `FilterParameterArgs`, etc.
|
|
* **DTS.Common.Enums.Sensors**: `CalibrationBehaviors`, `IsoViewMode`.
|
|
* **DTS.Serialization**: Referenced via `Utils.SetChannelInfo` for lazy loading channel metadata.
|
|
|
|
### Events Consumed
|
|
* `RaiseNotification`
|
|
* `FilterParameterChangedEvent`
|
|
* `TestSummaryChangeNotification`
|
|
* `TestModificationChangedEvent`
|
|
* `CalibrationBehaviorSettingChangedEvent`
|
|
* `CalibrationBehaviorSettableInViewerChangedEvent`
|
|
* `ChannelCodesViewChangedEvent`
|
|
|
|
### Events Published
|
|
* `GraphClearNotification`
|
|
* `GraphLoadedCountNotification`
|
|
* `GraphSelectedChannelCountNotification`
|
|
* `GraphSelectedChannelsNotification`
|
|
* `BusyIndicatorChangeNotification`
|
|
* `FilterParameterChangedEvent`
|
|
|
|
## 5. Gotchas
|
|
|
|
* **Member Hiding**: The class uses the `new` keyword to hide base members (`ConfirmationRequest`, `PropertyChanged`, `OnPropertyChanged`, `IsBusy`, `IsDirty`). Accessing these via a base class reference will bypass the logic defined in `GraphMainViewModel`.
|
|
* **Explicit GC Collection**: The `CleanSelection` method explicitly calls `GC.Collect()`. This is generally discouraged in .NET development and could introduce performance pauses.
|
|
* **Lazy Loading Side Effect**: Inside `OnTestSummaryChanged`, there is a check `if (l.Channels.FirstOrDefault() == null)`. If true, it triggers `Utils.SetChannelInfo`, which modifies `l.Channels`, `l.Graphs`, and `l.CalculatedChannels` in place. This suggests the data object passed via the event is mutable and potentially incomplete prior to this handler executing.
|
|
* **Calibration Logic Mutation**: The `OnTestSummaryChanged` method modifies the `tsChannels` list (removing items or modifying `ChannelDescriptionString`) based on `calibrationBehaviorSetting`. This alters the data before it is displayed, specifically handling Linear vs. NonLinear calibration duplicates.
|
|
* **Dead Code / Empty Handlers**:
|
|
* The subscription to `GraphChannelsReadCompletedNotification` is commented out with the note "It does not work".
|
|
* Event handlers `TestChannelsTree_PropertyChanged` and `GraphList_PropertyChanged` contain empty `if` blocks (e.g., `if (e.PropertyName != "TestChannelsTree") { }`), which appears to be incomplete logic.
|
|
* `OnCalibrationBehaviorSettableInViewerChanged` is subscribed but has an empty implementation body. |