Files

119 lines
8.9 KiB
Markdown
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- DataPRO/Modules/TestSetups/TestSetupsList/ViewModel/TestSetupsListViewModel.cs
generated_at: "2026-04-16T04:51:29.820169+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "ed9dca56ffa30a15"
---
# ViewModel
## Documentation: `TestSetupsListViewModel`
---
### 1. **Purpose**
This module implements the view model for the Test Setups list UI, responsible for managing the display, filtering, sorting, and selection of test setups in the application. It acts as the intermediary between the `ITestSetupsListView` (view) and the underlying data (`ITestSetup[]`), coordinating with Prisms event aggregation system to decouple UI interactions (e.g., selection, double-click) from other system components. It supports multi-field filtering, column-based sorting, busy state indication, and notification display via interaction requests.
---
### 2. **Public Interface**
#### **Properties**
| Property | Type | Description |
|---------|------|-------------|
| `View` | `ITestSetupsListView` | Reference to the associated view; views `DataContext` is set to `this` in constructor. |
| `NotificationRequest` | `InteractionRequest<Notification>` | Prism interaction request used to raise notification popups. |
| `ConfirmationRequest` | `InteractionRequest<Confirmation>` | Prism interaction request used to raise confirmation dialogs. |
| `SelectedTestSetupIndex` | `int` | Zero-based index of the currently selected item in the list view; defaults to `-1`. |
| `SelectedTestSetupItems` | `BulkObservableCollection<ITestSetup>` | Collection of currently selected test setups; raises `TestSetupsListTestSetupSelectedEvent` on change. |
| `TestSetups` | `ITestSetup[]` | Current filtered/sorted list of test setups displayed in the view. |
| `IsDirty` | `bool` | Read-only; always `false` (no dirty state tracked). |
| `IsBusy` | `bool` | Indicates whether a long-running operation is in progress; updated via `BusyIndicatorChangeNotification` event. |
| `IsMenuIncluded` | `bool` | Controls visibility of menu UI elements. |
| `IsNavigationIncluded` | `bool` | Controls visibility of navigation UI elements. |
| `ListViewId` | `string` | Returns `"TestSetupsListView"`; used for event scoping. |
#### **Methods**
| Method | Signature | Description |
|--------|-----------|-------------|
| `ClearAllFilters` | `public void ClearAllFilters()` | Clears all per-field search terms stored in `_currentSearchTermByField`. |
| `Unset` | `public void Unset()` | Resets internal state: clears `_allTestSetup` and `TestSetups`, clears filters, and publishes `ListViewStatusEvent` with status `Unloaded`. |
| `Sort` | `public void Sort(object o, bool bColumnClick)` | Sorts `TestSetups` by field (`o` as `string` tag parsed to `TestSetupFields`). If `bColumnClick` is `true`, toggles sort direction on repeated clicks of same column; otherwise, applies current sort without toggling. |
| `Filter` | `public void Filter(object objectTag, string term)` | Sets per-field search term for `TestSetupFields` parsed from `objectTag`, then invokes `Filter(string)`. |
| `Filter` | `public void Filter(string term)` | Applies global search `term` (case-insensitive substring match) across *all* fields using `ITestSetup.Filter(string)` and `TestSetupFilter`. Updates `TestSetups`. |
| `SetTestSetups` | `public void SetTestSetups(ITestSetup[] allTestSetupsForUser)` | Sets `_allTestSetup`, then applies current filter and sort to populate `TestSetups`. |
| `Cleanup` | `public void Cleanup()` | No-op. |
| `CleanupAsync` | `public Task CleanupAsync()` | Returns `Task.CompletedTask`. |
| `Initialize` / `InitializeAsync` | Multiple overloads | All no-ops; no initialization logic implemented. |
| `Activated` | `public void Activated()` | No-op. |
| `MouseDoubleClick` | `public void MouseDoubleClick(int index)` | If valid index and exactly one item selected, publishes `TestSetupsListEditTestSetupEvent` with the selected test setups `Name`. |
#### **Private Helpers**
| Method | Signature | Description |
|--------|-----------|-------------|
| `TestSetupFilter` | `private bool TestSetupFilter(ITestSetup t)` | Implements per-field filtering logic: for each field with a non-empty search term, checks case-insensitive substring match (or boolean conversion for `IsComplete`). Returns `false` if any field fails. |
| `FireSelectionChanged` | `private void FireSelectionChanged()` | Publishes `TestSetupsListTestSetupSelectedEvent` with array of selected test setup names. |
| `SelectedTestSetupItemsOnCollectionChanged` | `private void SelectedTestSetupItemsOnCollectionChanged(...)` | Handles `CollectionChanged`; skips re-firing selection event if `GetUpdating()` returns `true` and collection is non-null/non-empty (workaround for bug #18382). |
---
### 3. **Invariants**
- `TestSetups` is always a subset of `_allTestSetup`, filtered and sorted per current criteria.
- `_currentSearchTermByField` keys are exclusively `TestSetupFields` enum values.
- `SelectedTestSetupItems.CollectionChanged` event is subscribed exactly once per assignment (unsubscribes old, subscribes new).
- `IsBusy` is updated only via subscription to `BusyIndicatorChangeNotification` event.
- `ListViewId` is constant: `"TestSetupsListView"`.
- `SelectedTestSetupItems` defaults to a `BulkObservableCollection<ITestSetup>`; never `null` after construction.
- `TestSetups` is initialized as `new ITestSetup[0]` in `Unset()` and constructor; never `null`.
- `Sort()` ensures `TestSetups` is never left unsorted; if already sorted, flips direction and re-sorts.
---
### 4. **Dependencies**
#### **Imports/Usings (External)**
- `Prism.Events` (`IEventAggregator`, `EventBase`)
- `Prism.Regions` (`IRegionManager`)
- `Unity` (`IUnityContainer`)
- `DTS.Common.Events.*` (e.g., `RaiseNotification`, `BusyIndicatorChangeNotification`, `ListViewStatusEvent`, `TestSetupsListEditTestSetupEvent`, `TestSetupsListTestSetupSelectedEvent`)
- `DTS.Common.Interface.TestSetups.TestSetupsList` (`ITestSetupsListView`, `ITestSetup`)
- `DTS.Common.Enums.TestSetups.TestSetupList` (`TestSetupFields`, `ListViewStatusArg`)
- `DTS.Common.Interactivity` (`InteractionRequest<Notification>`, `InteractionRequest<Confirmation>`)
- `DTS.Common.Classes` (`BulkObservableCollection<T>`)
#### **Internal Dependencies**
- `TestSetupsList.Model` namespace (likely contains `TestSetupComparer`, `ITestSetup` implementations).
- `ITestSetup` interface must define:
- `Name`, `Description`, `RecordingMode`, `PreTriggerSeconds`, `PostTriggerSeconds`, `LastModified`, `LastModifiedBy`, `IsComplete` properties.
- `Filter(string term)` method for global search.
#### **Consumers (Inferred)**
- `TestSetupsListEditTestSetupEvent` subscribers (e.g., edit view model/controller).
- `TestSetupsListTestSetupSelectedEvent` subscribers (e.g., detail view or command handlers).
- `ListViewStatusEvent` subscribers (e.g., layout or state manager).
- `RaiseNotification` and `BusyIndicatorChangeNotification` publishers.
---
### 5. **Gotchas**
- **`IsDirty` is unused**: Always `false`; no dirty state tracking is implemented despite property existence.
- **`Initialize*` and `Cleanup*` methods are no-ops**: Despite implementing Prisms `INavigationAware`/`IInitializeAsync` patterns, no initialization or cleanup logic is present.
- **`Sort()` behavior on identical sequences**: If the list is already sorted, it flips `_sortAscending` and re-sorts — this may cause unexpected sort direction toggling on first sort if data was pre-sorted.
- **`TestSetupFilter` uses `Convert.ToBoolean(term)` for `IsComplete`**: Fails if `term` is not `"True"`/`"False"` (case-insensitive); throws `FormatException` for invalid strings.
- **`MouseDoubleClick` requires exactly one selected item**: Double-click only triggers edit if `SelectedTestSetupItems.Count == 1`; multi-select disables this behavior.
- **Bug workaround in `SelectedTestSetupItemsOnCollectionChanged`**: Skips `FireSelectionChanged()` when `GetUpdating()` returns `true` *and* collection is non-empty — relies on external `DTS.Common.Enums.SelectedItemsStatus.GetUpdating()` logic (not visible here).
- **No validation on `Filter` term**: Non-numeric `term` for `IsComplete` will cause `Convert.ToBoolean(term)` to throw.
- **`ClearAllFilters()` does not re-apply current global filter**: Only clears per-field terms; global `_currentSearchFilter` remains unchanged, but `TestSetups` is not recomputed until `Filter(string)` is called again.
- **Thread safety**: `OnBusyIndicatorNotification` uses `ThreadOption.PublisherThread`, but other event handlers (`OnRaiseNotification`) use default (likely background thread); UI updates (`IsBusy`, `NotificationRequest.Raise`) must be marshaled to UI thread — Prism handles this via `InteractionRequest`, but `IsBusy` property setter calls `OnPropertyChanged` directly (assumes `INotifyPropertyChanged` subscribers are thread-aware or dispatcher is used elsewhere).
---
*Documentation generated from `TestSetupsListViewModel.cs` alone. Behavior not derivable from source is marked as unknown.*