Files
2026-04-17 14:55:32 -04:00

10 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/Modules/Channels/ChannelCodes/ViewModel/ChannelCodesListViewModel.cs
2026-04-17T16:02:02.258497+00:00 zai-org/GLM-5-FP8 1 4a52e53369e1f84f

ChannelCodesListViewModel Documentation

1. Purpose

ChannelCodesListViewModel is a Prism-based ViewModel that manages the display, editing, validation, and persistence of Channel Codes in a WPF application. It handles two distinct categories of channel codes—ISO and User—providing separate views for each via a ViewMode toggle. The ViewModel supports CRUD operations, multi-selection, copy/paste functionality, sorting, filtering, and event-driven communication with other application components. It implements IChannelCodesListViewModel and follows the MVVM pattern with INotifyPropertyChanged support.


2. Public Interface

Properties

Property Type Description
View IChannelCodesListView The associated view instance; DataContext is set to this ViewModel in constructor.
NotificationRequest InteractionRequest<Notification> Used to raise notification dialogs.
ConfirmationRequest InteractionRequest<Confirmation> Used to raise confirmation dialogs.
AllISOChannelCodes List<IChannelCode> Complete list of ISO channel codes (unfiltered).
AllUserChannelCodes List<IChannelCode> Complete list of User channel codes (unfiltered).
ISOChannelCodes ObservableCollection<IChannelCode> Filtered ISO channel codes bound to the view.
UserChannelCodes ObservableCollection<IChannelCode> Filtered User channel codes bound to the view.
SelectedCodes IChannelCode[] Returns selected codes based on current ViewMode.
Page object Page identifier used in event payloads.
IsDirty bool Indicates unsaved changes.
IsBusy bool Controls busy indicator state.
IsMenuIncluded bool Controls menu inclusion.
IsNavigationIncluded bool Controls navigation inclusion.
IsReadOnly bool When true, disables editing (FB14098).
ViewMode ViewModes Current view mode (ISO or User).
ISOVisibility Visibility Returns Visible when ViewMode.ISO, else Collapsed.
UserVisibility Visibility Returns Visible when ViewMode.User, else Collapsed.
ChannelCodesFunc Func<IList<IChannelCode>> Returns ChannelCode.ChannelCodes.
ShowISOStringBuilder bool Controls ISO string builder visibility.
UniqueISOCodesRequired bool Indicates whether unique ISO codes are required.
ShowChannelCodeLookupHelper bool Controls channel code lookup helper visibility.

Methods

Method Signature Description
OnPropertyChanged void OnPropertyChanged(string propertyName) Raises PropertyChanged event.
Remove void Remove(IChannelCode channel) Removes a channel code; routes to RemoveISOChannel or RemoveUserChannel based on CodeType. Publishes PageModifiedEvent.
MarkModified void MarkModified(IChannelCode channel) Marks a channel as modified; adds a new blank row if modifying the last item. Publishes PageModifiedEvent.
Unset void Unset() Clears all channel code collections.
SetPage void SetPage(object page) Sets the Page identifier for event routing.
OnSetActive void OnSetActive() Loads existing channel codes from database, populates collections, sorts and filters.
Cleanup void Cleanup() Empty cleanup method.
CleanupAsync Task CleanupAsync() Returns Task.CompletedTask.
Initialize void Initialize() / void Initialize(object parameter) / void Initialize(object parameter, object model) Empty initialization methods.
InitializeAsync Task InitializeAsync() / Task InitializeAsync(object parameter) Return Task.CompletedTask.
Activated void Activated() Empty activation method.
ReportErrors void ReportErrors(string[] errors) Publishes PageErrorEvent with errors and Page.
Save bool Save() Persists all changes using a 4-step process: delete removed codes, update existing, insert new, update IDs. Returns true on success.
ValidateISO void ValidateISO(ref List<string> errors, ref List<string> warnings) Validates ISO channel codes.
ValidateUser void ValidateUser(ref List<string> errors, ref List<string> warnings) Validates User channel codes.
Validate bool Validate(bool bDisplayWindow) Validates all codes; optionally displays errors/warnings. Returns true if no errors.
CopySelected void CopySelected() Copies selected codes; inserts copies before the last (blank) row.
DeleteSelected void DeleteSelected() Deletes selected codes; ensures a blank row remains at the end.
SetISOSelection void SetISOSelection(IChannelCode[] channelCodes) Sets ISO selection; publishes PageSelectionChanged if ViewMode.ISO.
SetUserSelection void SetUserSelection(IChannelCode[] channelCodes) Sets User selection; publishes PageSelectionChanged if ViewMode.User.
Filter void Filter(object columnTag, string searchTerm) Filters codes based on column tag ("ISOCode", "ISOChannelName", "UserCode", "UserChannelName").
Sort void Sort(object columnTag, bool bColumnClick) Sorts codes by column; toggles direction on repeated clicks.

Nested Types

Type Description
enum Fields IsoCode, IsoChannelName, UserCode, UserChannelName — used for sorting/filtering.
enum ViewModes ISO, User — toggles between channel code types.
class ChannelComparer : IComparer<IChannelCode> Custom comparer using NaturalStringComparer; handles null/blank items by sorting them last.

3. Invariants

  1. Blank Row Guarantee: The last item in both AllISOChannelCodes and AllUserChannelCodes is always a blank ChannelCode instance (both Code and Name are empty). This serves as the "new row" for data entry.

  2. ISO Code Length: ISO codes are silently truncated to 16 characters maximum in ParseText().

  3. Blank Item Sorting: Items with both Code and Name empty are always sorted to the end of the list (see ChannelComparer.Compare).

  4. Selection Handling: Empty selection arrays are ignored and not assigned (FB 18906 guard in SetISOSelection and SetUserSelection).

  5. Save Operation Ordering: The Save() method executes in strict order: (1) delete removed codes, (2) update existing codes, (3) insert new codes. This prevents primary key conflicts.

  6. Event Subscription Pattern: The static _bAddListeners flag ensures event listeners are only registered on the second constructor invocation (see Gotchas).


4. Dependencies

External Dependencies (Imports)

Namespace Purpose
ChannelCodes.Model ChannelCode model, ChannelCodeType lookup
DTS.Common.Enums General enumerations
DTS.Common.Enums.Channels ChannelEnumsAndConstants
DTS.Common.Events PageModifiedEvent, PageErrorEvent, PageSelectionChanged
DTS.Common.Events.ChannelCodes RaiseNotification, BusyIndicatorChangeNotification, TextPastedEvent, ChannelCodeCommittedEvent
DTS.Common.Interface.Channels.ChannelCodes IChannelCode, IChannelCodesListView, IChannelCodesListViewModel
DTS.Common.Utilities.Logging APILogger
DTS.Common.Interactivity InteractionRequest<T>, Notification, Confirmation
Prism.Events IEventAggregator, ThreadOption
Prism.Regions IRegionManager
Unity IUnityContainer

Event Subscriptions

Event Thread Option Keep Subscriber Reference
RaiseNotification Default Default
BusyIndicatorChangeNotification PublisherThread true
TextPastedEvent Default Default
ChannelCodeCommittedEvent PublisherThread true

Event Publications

Event Payload
PageModifiedEvent PageModifiedArg with status (Modified/Saved) and Page
PageErrorEvent PageErrorArg with error messages and Page
PageSelectionChanged PageSelectionChangedArg with selection count and Page

5. Gotchas

  1. Static Listener Flag Hack: The constructor uses a static _bAddListeners field to prevent duplicate event subscriptions. The comment explicitly states: "this is a hack, the app startup is calling this, then the app itself, we only want the app itself to be handling the listeners." This implies the constructor is invoked twice during application lifecycle, and only the second invocation should register TextPastedEvent and ChannelCodeCommittedEvent handlers.

  2. Silent ISO Code Truncation: In ParseText(), ISO codes exceeding 16 characters are silently truncated without warning or error. Users are not notified of this modification.

  3. Paste Behavior Depends on Tag: The PasteIso and PasteUser methods interpret the tag parameter to determine whether pasted text should populate the Code or Name field when single-column data is pasted. The tag must equal "ISOCode" or "UserCode" (string comparison) to populate the code field.

  4. Filter Uses Case-Insensitive Contains: Filtering uses IndexOf(term, StringComparison.CurrentCultureIgnoreCase) which performs a substring match, not an exact or startswith match.

  5. Save Returns False Only on Exception: The Save() method returns false only if an exception is caught. Validation errors do not prevent save; callers should call Validate() before Save().

  6. Remove vs DeleteSelected Behavior Difference: Remove() does not automatically add a blank row if removing a non-last item, but DeleteSelected() and RemoveISOChannel/RemoveUserChannel do add a blank row when removing the last item. This ensures the blank row invariant is maintained.