--- source_files: - Common/DTS.Common/Classes/ChannelCodes/TextPastedArgs.cs - Common/DTS.Common/Classes/ChannelCodes/ChannelCode.cs generated_at: "2026-04-16T03:15:37.036883+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "936720bfac8d31e1" --- # ChannelCodes ## Documentation: ChannelCode Module ### 1. Purpose This module provides core data structures and command logic for handling channel codes in the DTS system. It defines the `ChannelCode` class (a concrete implementation of `IChannelCode`) that represents a channel with an identifier, code string, name, type (User/ISO), and status, and includes constructors for instantiation from database readers or other channel codes. It also defines `TextPastedArgs`, a data carrier for paste events, and `PasteCommandClass`, a `ICommand` implementation that intercepts text paste operations on UI text boxes, processes clipboard content, and publishes structured events (`TextPastedEvent`) when multi-field or structured paste occurs—while allowing simple single-field pastes to be handled by standard text change logic. The module supports UI binding, event-driven architecture (via Prism’s `IEventAggregator`), and ISO code coercion via a delegate. --- ### 2. Public Interface #### `TextPastedArgs` class - **`TextPastedArgs(string text, IChannelCode channelCode, string id, object tag)`** Constructor. Initializes a new instance with the pasted `text`, the `channelCode` (used as `Sender`), a unique `id` (e.g., `"ChannelCode"`), and an arbitrary `tag` (typically from the UI element). - **`string Text { get; }`** The raw text content that was pasted (from clipboard). - **`object Sender { get; }`** The `IChannelCode` instance associated with the paste operation (set from the `channelCode` parameter). - **`string Id { get; }`** A string identifier for the paste operation (e.g., `"ChannelCode"`). - **`object Tag { get; }`** The `Tag` property of the UI element (e.g., `TextBox`) where the paste occurred. #### `ChannelCode` class - **`ChannelCode(IDataReader reader, IReadOnlyDictionary channelTypeLookup)`** Constructor. Populates the instance from an `IDataReader` by reading `"Id"`, `"Code"`, `"CodeTypeInt"`, and `"Name"` fields. Uses `channelTypeLookup` to map `CodeTypeInt` to `ChannelCodeType.User` or `.ISO`. - **`ChannelCode()`** Default constructor. Initializes `CodeType` to `ChannelCodeType.ISO`. - **`ChannelCode(IChannelCode channelCode)`** Copy constructor. Copies `Id`, `Code`, `Name`, and `CodeType` from another `IChannelCode`. - **`int Id { get; set; }`** The numeric identifier of the channel code. Initialized to `-1` by default. - **`UIItemStatus ItemStatus { get; set; }`** Status of the item (e.g., Added, Modified, Deleted). Initialized to `UIItemStatus.None`. - **`string Code { get; set; }`** The code string (e.g., `"A1"`). Protected backing field `_code`. - **`string Name { get; set; }`** The human-readable name. Protected backing field `_name`. - **`ChannelCodeType CodeType { get; set; }`** Enumerated type of the code (`User` or `ISO`). - **`const string PASTE_ID = "ChannelCode"`** A constant identifier used for paste operations (note: `PasteCommandClass` uses its own `Id` parameter, not this constant). - **`ICommand PasteCommand { get; set; } = null`** Command bound to paste operations (e.g., Ctrl+V). Defaults to `null` to avoid exceptions during UI construction. - **`override bool Equals(object obj)`** Compares two `ChannelCode` instances for equality based on `Code`, `Name`, and `CodeType` (case-sensitive string equality). Returns `false` if `obj` is not a `ChannelCode`. - **`~ChannelCode()`** Finalizer. Clears `_code` and `_name` to `null` to reduce memory footprint if the object is held longer than expected before cleanup. #### `PasteCommandClass` class - **`PasteCommandClass(string id)`** Constructor. Stores the `id` in the `Id` property. - **`string Id { get; }`** Identifier for this paste command instance (e.g., `"ChannelCode"` or a unique control ID). - **`bool CanExecute(object parameter)`** Always returns `true`. - **`void Execute(object parameter)`** Executes the paste logic: - Validates `parameter` is a `TextBox`. - Resolves `IChannelCode` from `TextBox.DataContext`, supporting `ChannelCodeBuilder` and `ChannelNameBuilder` wrappers. - Reads clipboard text. - If clipboard text is a single line *without* delimiters (`,`, `;`, `\t`), publishes `PageModifiedEvent` and returns early (no structured paste). - Otherwise, clears `Code` and `Name` (via self-assignment to trigger property change), then publishes `TextPastedEvent` with a `TextPastedArgs` instance containing the clipboard text, channel code, `Id`, and `TextBox.Tag`. - Catches exceptions and publishes `PageErrorEvent` with the error message. - **`event EventHandler CanExecuteChanged`** Required by `ICommand`; not raised by this implementation. #### `CoerceISOCodeDelegate` delegate - **`string CoerceISOCodeDelegate(string val, bool uniqueISOCodesRequired, bool useISOCodeFilterMapping)`** A delegate for custom logic to transform or validate an incoming ISO code string (`val`) before assignment, based on system constraints (`uniqueISOCodesRequired`, `useISOCodeFilterMapping`). Used to enforce ISO code uniqueness or apply filtering rules. --- ### 3. Invariants - **`ChannelCode.Code` and `ChannelCode.Name` must be non-null strings** (though they may be empty). The `Code` and `Name` properties use `SetProperty`, implying change notifications are raised on assignment. - **`ChannelCode.Id` defaults to `-1`** and is only valid when set to a non-negative integer (typically from database). - **`ChannelCode.CodeType` defaults to `ChannelCodeType.ISO`** when constructed via the parameterless constructor. - **`TextPastedArgs.Text` is the raw clipboard content** at the time of paste, including any embedded delimiters. - **`TextPastedArgs.Sender` is always the resolved `IChannelCode` instance** (or `null` if resolution fails—though the `PasteCommandClass.Execute` method returns early if resolution fails, so `Sender` should never be `null` in published events). - **`PasteCommandClass.CanExecute` always returns `true`**, meaning paste is always enabled in the UI. - **Single-line, non-delimited paste bypasses `TextPastedEvent`** and only triggers `PageModifiedEvent`. --- ### 4. Dependencies - **Depends on:** - `DTS.Common.Events` (for `PageModifiedEvent`, `TextPastedEvent`, `PageErrorEvent`, `PageModifiedArg`, `TextPastedArgs`, `PageErrorArg`). - `DTS.Common.Interface.Channels.ChannelCodes` (for `IChannelCode` interface). - `Prism.Events` (for `IEventAggregator`). - `Prism.Ioc` (for `ContainerLocator.Container`). - `DTS.Common.Base` (for `BasePropertyChanged`, enabling `INotifyPropertyChanged`). - `DTS.Common.Controls`, `DTS.Common.Enums`, `DTS.Common.Enums.Channels` (for `UIItemStatus`, `ChannelEnumsAndConstants`, `ChannelCodeType`). - `System.Data` (`IDataReader`), `System.Windows` (`TextBox`, `ICommand`), `System.Windows.Controls`. - `DTS.Common.Utility` (for `Utility.GetInt`, `Utility.GetString`, `Utility.GetShort`). - **Depended on by:** - UI components (e.g., `TextBox` controls) that bind `PasteCommand` to `PasteCommandClass`. - Event handlers for `TextPastedEvent` (to process structured paste). - `ChannelCodeBuilder` and `ChannelNameBuilder` (implied by `PasteCommandClass.Execute` checking for their `DataContext`). --- ### 5. Gotchas - **`PASTE_ID` constant is unused in `PasteCommandClass`**: The `PasteCommandClass` uses its own `Id` parameter (passed to its constructor) instead of the `ChannelCode.PASTE_ID` constant. This may cause confusion if expecting consistency. - **Self-assignment of `Code`/`Name` in `Execute`**: The lines `channelCode.Code = channelCode.Code;` are used to trigger property change notifications *without* modifying the value. This is a workaround to force UI updates before publishing `TextPastedEvent`. - **`PasteCommand` defaults to `null`**: To avoid exceptions during UI construction (per comment), `PasteCommand` is not initialized. UI must explicitly assign a `PasteCommandClass` instance. - **`Equals` ignores `Id`**: Two `ChannelCode` instances with different `Id` but identical `Code`, `Name`, and `CodeType` are considered equal. This may be intentional for business logic (e.g., comparing definitions) but could cause issues if `Id` is expected to be unique. - **`CanExecuteChanged` is never raised**: `PasteCommandClass` implements `ICommand` but does not raise `CanExecuteChanged`. UI frameworks relying on this event (e.g., WPF) may not update command availability dynamically. - **Clipboard access is synchronous**: `Clipboard.GetText()` is called directly in `Execute`, which may block the UI thread or throw if clipboard access is denied. Error handling only captures exceptions and publishes `PageErrorEvent`. - **`TextPastedArgs.Sender` is typed as `object`**: Though it is always an `IChannelCode`, the interface uses `object` instead of `IChannelCode`, requiring casting by consumers.