11 KiB
source_files, generated_at, model, schema_version, sha256
| source_files | generated_at | model | schema_version | sha256 | |
|---|---|---|---|---|---|
|
2026-04-16T04:45:51.906727+00:00 | Qwen/Qwen3-Coder-Next-FP8 | 1 | f514e88931e0b70e |
GroupImportViewModel Documentation
1. Purpose
GroupImportViewModel is the central view model for the group and channel import functionality in the DTS application. It orchestrates the end-to-end workflow of importing data from .grp files—parsing file contents, validating sensor and field data, allowing user review and selection of groups/channels for import, and committing validated data to the database via background processing. It serves as the data context for three distinct views (IGroupImportOptionsView, IGroupImportPreviewView, IGroupImportImportView) and integrates with Prism’s region management, event aggregation, and Unity DI container to coordinate UI state and external service calls.
2. Public Interface
Constructor
public GroupImportViewModel(
IGroupImportOptionsView optionsView,
IGroupImportPreviewView previewView,
IGroupImportImportView importView,
IRegionManager regionManager,
IEventAggregator eventAggregator,
IUnityContainer unityContainer)
Initializes the view model, assigns views and their DataContext, sets up interaction requests (NotificationRequest, ConfirmationRequest), and subscribes to RaiseNotification and BusyIndicatorChangeNotification events.
Methods
-
void ParseSourceFiles(string userTags)
Reads and parses all.grpfiles listed inSourceFiles. For each file:- Extracts group name from file name (strips extension).
- Assigns
userTagstoGroupTagsandImportingUserTags. - Parses each non-empty line using
Parse()(supports escaped commas via parentheses). - Validates fields: expects 5 fields per line (
SensorSerialNumber,DisplayName,ISOCode,Invert,FullScale). - Reports errors for missing sensors (unless empty), invalid invert/full-scale values, wrong field count, or empty files.
- Populates
Groupsand callsProcessChannels().
-
void Import()
Starts the import process on a background thread viaThreadPool.QueueUserWorkItem(ImportFunc). -
private void ImportFunc(object o)
Background method that:- Fetches default channel settings via
DbOperations.GetChannelSettingDefaults(). - Updates UI progress state (
ImportProgressValue,ImportProgressBarVisibility,ImportProgressColor,DisableUI). - Iterates over included groups and their channels:
- Skips channels with critical errors (
FileEmpty,InvalidSensorInput,SensorNotFound). - For non-critical errors, uses
nullfor invalidFullScaleorInvert. - Calls
CreateGroup,AddChannel, and finallyCommitGroups.
- Skips channels with critical errors (
- Restores UI state on completion (though commented-out lines suggest UI reset is incomplete).
- Fetches default channel settings via
-
void SetStatus(string message, Color color)
UpdatesImportProgressText,ImportProgressColor,ImportProgressBarVisibility(collapsed), and invokesEnableUI. -
void Reset()
Clears all imported data:SourceFiles,Channels,Groups, progress state, and resetsImportProgressValueto 0. -
void CheckGroupName()
Validates group names:- Flags groups with duplicate names in the import set.
- Flags groups whose name already exists in the application and
Overwriteisfalse. - Sets
GroupNameHasError = trueon invalid groups.
-
private static string[] Parse(string line)
Parses a single.grpline, respecting parenthetical escaping (e.g.,"this(,)is"→ one field"this(,)is"). -
private void ProcessChannels()
Flattens all channels fromGroupsinto theChannelsarray. -
void InvalidateChannels()
RaisesPropertyChangedforIncompleteChannelsandCompleteChannelscomputed properties. -
void Cleanup()/Task CleanupAsync()/void Initialize()/Task InitializeAsync()/void Activated()
No-op stubs; likely required by Prism interfaces (INavigationAware,IInitializeAsync, etc.) but not implemented.
Properties
-
IGroupImportOptionsView ImportOptionsView,IGroupImportPreviewView ImportPreviewView,IGroupImportImportView ImportView
References to the three associated views. -
string[] SourceFiles
Array of.grpfile paths to parse. -
GroupGRPImportGroup[] Groups
Parsed groups with their channels and errors. -
GroupGRPImportChannel[] Channels
Flattened list of all channels fromGroups. -
GroupGRPImportChannel[] IncompleteChannels
Channels in included groups that have non-recoverable errors (e.g.,SensorNotFound,InvalidSensorInput). These will not be imported. -
GroupGRPImportChannel[] CompleteChannels
Channels in included groups that either have no errors or have recoverable errors (InvalidFullScaleInput,InvalidInvertInput). These will be imported (withnullfor invalid fields). -
string ImportProgressText,Color ImportProgressColor,Visibility ImportProgressBarVisibility,double ImportProgressValue
UI state for the import progress bar. -
bool IsBusy
Bound to busy indicator; set viaOnBusyIndicatorNotification. -
InteractionRequest<Notification> NotificationRequest,InteractionRequest<Confirmation> ConfirmationRequest
Prism interaction requests for showing notifications and confirmation dialogs. -
bool IsDirty
Read-only; alwaysfalse(never set totruein source). -
bool IsMenuIncluded,bool IsNavigationIncluded
UI state flags (bound to menu/navigation visibility); no logic sets them beyond property change notifications. -
string HeaderInfo
Returns"MainRegion".
Commands
DelegateCommand ImportBrowseCommand
Opens a file dialog (OpenFileDialog) withMultiselect=true,FilterfromStringResources.ImportFileFilter, setsSourceFiles,BrowseOk=true, and navigates toSteps.PreviewviaSwitchNavSteps.
Delegates (Settable Properties)
-
CheckGroupExistsDelegate CheckGroupExists
Function to check if a group exists in the application. -
CheckSensorExistsDelegate CheckSensorExists
Function to check if a sensor exists. -
CreateGroupDelegate CreateGroup
Action to create a group. -
AddChannelToGroupDelegate AddChannel
Action to add a channel to a group. -
CommitGroupsDelegate CommitGroups
Action to commit groups to the database. -
Disable_UIDelegate DisableUI,Enable_UIDelegate EnableUI
Actions to disable/enable the UI during import. -
SwitchNavStepsDelegate SwitchNavSteps
Action to navigate between import steps (e.g.,Steps.Preview). -
FileUtils.LogDelegate Logger
Optional logging delegate; invoked on exceptions.
3. Invariants
- File Parsing: Each
.grpline must contain 5 comma-separated fields (or be empty/whitespace). Lines with fewer or more fields are marked withInvalidSensorInput. - Sensor Validation: A channel is flagged
SensorNotFoundifCheckSensorExistsis non-null, the sensor serial number is non-empty, andCheckSensorExists(sensorSerialNumber)returnsfalse. Empty sensor serial numbers are allowed (per comment referencing FB13753). - Invert Field: Accepts
"yes"/"no"(case-insensitive) orbool.TryParse-compatible strings. Invalid values triggerInvalidInvertInput. - FullScale Field: Must parse as
double; otherwise,InvalidFullScaleInput. - Group Name Uniqueness: Within the import set, duplicate group names are flagged. Across the import set and application, group names must be unique unless
Overwrite=true. - Import Progress State: During
ImportFunc,ImportProgressBarVisibilityis set toVisible,DisableUIis called, and progress is tracked. Completion logic is partially commented out, so UI may not fully reset. - Channel Inclusion Logic: Only channels from groups where
Included=trueare considered for import. Channels with critical errors (FileEmpty,InvalidSensorInput,SensorNotFound) are skipped entirely; others may be imported withnullfor invalid fields.
4. Dependencies
Imports/References
- DTS.Common:
Events(IEventAggregator,RaiseNotification,BusyIndicatorChangeNotification)Utils(FileUtils.LogDelegate)Classes.Groups(GroupGRPImportGroup,GroupGRPImportChannel,GroupGRPImportError)Enums.Groups(GroupImportEnums.Steps,GroupGRPImportError.Errors)Interface.Groups(IGroupImportOptionsView,IGroupImportPreviewView,IGroupImportImportView,IGroupImportViewModel)Storage(DbOperations)Interactivity(InteractionRequest<T>)
- Prism:
Regions(IRegionManager)Events(IEventAggregator)DelegateCommand
- Unity (
IUnityContainer) - System.Windows (
Visibility,Color) - System.Windows.Forms (
OpenFileDialog) - StringResources (resource strings for UI messages)
Dependencies on External Services
DbOperations.GetChannelSettingDefaults()— for default channel settings.CheckSensorExists,CheckGroupExists,CreateGroup,AddChannel,CommitGroups— injected delegates for database operations.SwitchNavSteps— navigation delegate (likely from a parent view model or shell).
5. Gotchas
- Incomplete UI Reset After Import:
ImportFuncsetsImportProgressBarVisibility = Visibility.VisibleandDisableUI, but the corresponding reset (Visibility.Collapsed,EnableUI) is commented out. This may leave the UI in a disabled state if import completes without error. - Empty Sensor Serial Numbers Are Allowed: Despite
CheckSensorExistsvalidation, empty serial numbers bypass theSensorNotFoundcheck (FB13753). - Partial Error Tolerance: Channels with
InvalidFullScaleInputorInvalidInvertInputare included inCompleteChannelsand imported, but withnullfor the invalid field. This may cause downstream issues if the database or business logic does not handlenullgracefully. - No Validation of Group Name Format: Only existence and duplication are checked; no format validation (e.g., reserved characters, length limits) is implemented.
Parse()Escaping Logic: Parentheses are treated as literal characters only when nested (vialeftParenCount). A single(or)without matching pairs is still treated as a delimiter if not balanced.IsDirtyNever Set: TheIsDirtyproperty is declared but never updated, so it always returnsfalse.Initialize*andCleanup*Methods Are No-ops: These likely exist to satisfy Prism interfaces but contain no logic.ChannelsProperty TriggersInvalidateChannels(): SettingChannelsraises property change notifications forIncompleteChannelsandCompleteChannels, but these are computed properties—modifyingChannelsdirectly may not reflect changes in the UI ifGroupsis not updated.- Thread Safety:
ImportFuncruns on a background thread but updates UI properties directly (e.g.,ImportProgressValue). While Prism’sINotifyPropertyChangedmay handle thread marshaling in some cases, this pattern is fragile and may cause cross-thread exceptions if the UI framework is strict.