9.7 KiB
source_files, generated_at, model, schema_version, sha256
| source_files | generated_at | model | schema_version | sha256 | |
|---|---|---|---|---|---|
|
2026-04-16T04:47:12.822358+00:00 | Qwen/Qwen3-Coder-Next-FP8 | 1 | efb48e4bf6e2c1c7 |
ViewModel
Documentation: GroupListViewModel
1. Purpose
GroupListViewModel is the core view model for the Group List UI module. It manages the display, filtering, sorting, selection, and lifecycle of IGroup entities within the application. It acts as the intermediary between the IGroupListView view and the underlying group data model (Group), handling user interactions (e.g., double-click to edit, filtering/sorting), coordinating background operations (e.g., loading test setup lists), and publishing/subscribing to domain events via IEventAggregator. It supports both single- and multi-select group operations and integrates with the Prism region management and Unity DI container.
2. Public Interface
Constructors
GroupListViewModel(IGroupListView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)
Initializes the view model. Sets up the view binding, event subscriptions (e.g.,RaiseNotification,BusyIndicatorChangeNotification), and initializesSelectedGroupItemsas anObservableCollection<IGroup>.
Public Methods
-
void ClearAllFilters()
Clears all per-field filter terms stored in_filterByField. -
void MouseDoubleClick(int index)
If a single group is selected andindexis valid, publishes aGroupListEditGroupEventwith the selected group’sId. -
void Filter(string term)
SetsCurrentSearchTermtoterm, then re-applies sorting (which triggers filtering and re-sorting ofGroups). -
IGroup GetGroup(int? id, bool updateTags = true)
Returns the group with the givenid(ifid >= 0). IfupdateTagsistrue, updates the global tag cache before fetching. Returns a new emptyGroup()if not found. -
IGroup GetGroup(string displayName)
Returns the non-embedded group matchingdisplayName, preferring non-embedded over embedded groups (for backward compatibility with pre-2.0 group types). Returnsnullif none found. -
IGroup[] GetGroups(int[] ids)
Returns an array of groups whoseIds are inids, preserving order only in that groups not inidsare removed (i.e., order is not guaranteed to matchidsorder). -
IGroup[] GetAllGroups()
Returns all groups (viaGroup.GetAllGroups()), unfiltered and unsorted. -
void DeleteGroups(int[] ids)
Deletes groups with givenids. For each group, nullifiesStaticGroupIdon all related embedded groups, deletes the group, updatesAllGroups, and re-applies filters. Publishes errors viaPageErrorEvent. -
IGroup CreateGroup()
Returns a new unsavedGroup(true)(likely a new transient instance). -
IGroup CreateGroup(SqlDataReader, List<string>, List<int>)
Constructs aGroupfrom a data reader and hardware/test setup lists. -
IGroup CreateGroup(IGroupDbRecord, List<string>, List<int>)
Constructs aGroupfrom a database record and hardware/test setup lists. -
IGroup CreateGroup(List<string>)
Constructs a newGroupwith the givenincludedHardwareStringList. -
void Filter(object tag, string term)
Parsestagas aGroupFieldsenum value; if successful, storestermin_filterByField[tag], sets_sortField, and callsFilter(term). -
void OnSetActive(object page, bool groupTile, object o)
SetsPage, filtersAllGroupsto groups compatible with the current user’s role/tags, and either callsGetTestSetupListsAsync()(ifgroupTile == true) orSort(). -
private void GetTestSetupListsAsync()
Runs asynchronously: sets app status to busy, iterates overAllGroupsin parallel to callg.SetTestSetupLists(), then re-sorts on the UI thread. -
void Unset()
ClearsAllGroups,Groups, filters, and publishesListViewStatusEventwith statusUnloaded. -
void Sort(object o, bool bColumnClick)
SortsAllGroupsbyGroupFields(parsed fromo), appliesCurrentSearchTermand per-field filters (GroupFilter), and setsGroups. Updates sort direction on column click. -
void Cleanup()/Task CleanupAsync()/void Initialize()/Task InitializeAsync()/void Activated()
No-op stubs; likely required by Prism or custom interfaces but not implemented.
Public Properties
IGroupListView View– Bound view instance.InteractionRequest<Notification> NotificationRequest– For displaying notification popups.InteractionRequest<Confirmation> ConfirmationRequest– For confirmation dialogs.event PropertyChangedEventHandler PropertyChanged– ImplementsINotifyPropertyChanged.ObservableCollection<IGroup> SelectedGroupItems– Tracks selected groups; raisesGroupListGroupSelectedEventon change.IGroup[] Groups– Currently displayed (filtered + sorted) groups.bool IsBusy– Bound to busy indicator; updated viaOnBusyIndicatorNotification.bool IsMenuIncluded/bool IsNavigationIncluded– UI toggle flags.string ListViewId–"GroupListView"; used for event scoping.int SelectedGroupIndex– Index of selected group inGroups; default-1.
Private Properties (used in logic)
_filterByField: Dictionary<GroupFields, string>– Per-field filter terms.CurrentSearchTerm: string– Global search term._sortField: GroupFields– Current sort field (defaultLastModified)._sortAscending: bool– Sort direction (defaultfalse= descending)._comparer: GroupComparer– Comparison logic for sorting.
3. Invariants
Groupsis always a filtered and sorted subset ofAllGroups.AllGroupsis always filtered by user role and tag compatibility (viacurrentUser.TagCompatible(@group.TagIDs)).SelectedGroupItemsis anObservableCollection; changes triggerGroupListGroupSelectedEvent._filterByFieldstores per-field filter terms;CurrentSearchTermis a global term applied inSort.Groupsis sorted by_sortFieldin_sortAscendingorder usingGroupComparer.IsBusyis updated viaBusyIndicatorChangeNotificationevent (thread-safe subscription onPublisherThread).SelectedGroupItems.CollectionChangedhandler skips updates during flagged "updating" states (viaDTS.Common.Enums.SelectedItemsStatus.GetUpdating).
4. Dependencies
Imports / Dependencies Used
- Prism:
IEventAggregator,IRegionManager,Unity,Prism.Events,Prism.Regions,Prism.Interactivity. - DTS Common Libraries:
DTS.Common.Events.*(e.g.,RaiseNotification,BusyIndicatorChangeNotification,PageErrorEvent,AppStatusEvent,ProgressBarEvent,ListViewStatusEvent,GroupListEditGroupEvent,GroupListGroupSelectedEvent)DTS.Common.Interface.Groups.*(IGroup,IGroupListView,IGroupListViewModel)DTS.Common.Enums.Groups.GroupList.*(GroupFields,ListViewStatusArg)DTS.Common.Storage.*(DbOperations)DTS.Slice.Users.UserDTS.Common.Classes.Tags.TagsInstance
- .NET:
System.ComponentModel,System.Collections.ObjectModel,System.Threading.Tasks,System.Linq,System.Collections.Specialized,System.Windows,System.Data.SqlClient.SqlDataReader.
Dependencies on This Module
GroupListViewModelis exported via MEF ([PartCreationPolicy(CreationPolicy.Shared)]) and likely consumed by DI container resolution forIGroupListViewModel.IGroupListViewmust be provided at construction (likely via Prism view injection).- Other modules subscribe to events it publishes:
GroupListEditGroupEvent,GroupListGroupSelectedEvent,PageErrorEvent,ListViewStatusEvent.
5. Gotchas
- Sorting logic comment: The
Sortmethod contains commented-out logic suggesting a potential bug or inconsistency in handling already-sorted lists (especially forLastModified). This may cause unexpected sort direction toggling. GetGroup(string displayName)behavior: Returns only non-embedded groups if any exist; otherwise returnsnull. This may hide embedded groups unexpectedly.GetGroups(int[] ids)order: Output order is not guaranteed to match inputidsorder (usesContainsin reverse iteration).SelectedGroupItemssetter: Unsubscribes fromCollectionChangedonly if_selectedGroupItemswas non-null before assignment. IfSelectedGroupItemsis set multiple times, old handlers may leak if not handled carefully.OnSetActivefiltering: Filtering by user role/tag compatibility happens only inOnSetActive, not inFilterorSort. Thus, filtering/sorting operates on already-filteredAllGroups.GetTestSetupListsAsync: RunsSetTestSetupLists()in parallel (AsParallel().ForAll), but UI thread re-sort is done viaDispatcher.Invoke. Potential for race conditions ifSetTestSetupLists()modifies group state accessed during sort.GroupFiltercase sensitivity: UsesCompareOptions.OrdinalIgnoreCasefor all fields, includingLastModified(stringified) — may yield unexpected matches (e.g., "12" matches "12" but also "12" in "12/12/2023").- No validation on
DeleteGroups: Does not check if groups are in use (e.g., by tests); relies on underlyingGroup.Delete(id)to handle errors (which are then published viaPageErrorEvent). IsDirtyproperty: Declared but never set; alwaysfalse.Cleanup()/Initialize()stubs: AllInitialize*,Cleanup*, andActivated()methods are empty — may indicate incomplete implementation or reliance on external lifecycle management.
None identified beyond those above.