This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
---
source_files:
- Common/DTS.CommonCore/Classes/DTS.Viewer/Commands/RelayCommand.cs
generated_at: "2026-04-16T02:42:33.604683+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "63672ade54ed35d0"
---
# Commands
### **Purpose**
This module implements a concrete, reusable `ICommand`-based command class (`RelayCommand`) for WPF applications, enabling decoupling of UI actions (e.g., button clicks) from their execution logic. It serves as a lightweight command adapter that forwards `Execute` and `CanExecute` calls to user-provided delegates, supporting both mandatory execution logic and optional, parameterized execution guards. This pattern is foundational for implementing MVVM-style command binding in WPF.
---
### **Public Interface**
All members are public and part of the `RelayCommand` class.
- **`RelayCommand(Action<object> execute)`**
Constructor. Initializes the command with an execution delegate and no `CanExecute` guard (i.e., `CanExecute` always returns `true`). Throws `ArgumentNullException` if `execute` is `null`.
- **`RelayCommand(Action<object> execute, Predicate<object> canExecute)`**
Constructor. Initializes the command with both execution and guard delegates. Throws `ArgumentNullException` if `execute` is `null`. The `canExecute` parameter may be `null`, in which case `CanExecute` defaults to `true`.
- **`bool CanExecute(object parameter)`**
Implements `ICommand.CanExecute`. Invokes the stored `_canExecute` predicate (if non-null) with `parameter`; otherwise returns `true`.
- **`void Execute(object parameter)`**
Implements `ICommand.Execute`. Invokes the stored `_execute` action with `parameter`. No validation is performed on `parameter` beyond null-safety of the delegate itself.
- **`event EventHandler CanExecuteChanged`**
Implements `ICommand.CanExecuteChanged`. Subscribes/unsubscribes to `CommandManager.RequerySuggested`, enabling automatic re-evaluation of `CanExecute` when WPF detects relevant state changes (e.g., keyboard/mouse input, focus changes).
---
### **Invariants**
- `_execute` is **never null** after construction (enforced via `ArgumentNullException` in both constructors).
- `_canExecute` may be `null`; if so, `CanExecute` always returns `true`.
- `CanExecuteChanged` event handlers are **always** attached to `CommandManager.RequerySuggested`, ensuring WPFs command system triggers requery logic.
- No explicit validation is performed on the `parameter` passed to `Execute` or `CanExecute`; nulls are passed directly to the delegates.
---
### **Dependencies**
- **External Dependencies**:
- `System` (for `Action<T>`, `Predicate<T>`, `ArgumentNullException`)
- `System.Windows.Input` (for `ICommand`, `CommandManager`)
- **Internal Dependencies**:
- No other modules in the codebase are referenced (self-contained).
- **Depended Upon**:
- Likely consumed by WPF UI layers (e.g., `Button.Command` bindings) and view models throughout the `DTS.Viewer` subsystem.
---
### **Gotchas**
- **No manual `CanExecuteChanged` raising**: The class relies solely on `CommandManager.RequerySuggested` to trigger `CanExecute` re-evaluation. If the commands executability depends on non-UI state changes (e.g., background thread updates), callers must manually invoke `CommandManager.InvalidateRequerySuggested()` (or similar) to force updates.
- **Parameter handling**: The `parameter` passed to `Execute`/`CanExecute` is unvalidated. Passing `null` is permitted and will be forwarded to the delegates—consumers must handle `null` parameters explicitly if needed.
- **Thread affinity**: `CommandManager.RequerySuggested` is raised on the UI thread. If `CanExecute` delegates access non-UI-thread resources, thread-safety must be ensured by the caller.
- **No disposal pattern**: The class does not implement `IDisposable`, and event subscriptions (via `CanExecuteChanged`) are not explicitly cleaned up—relying on WPFs lifetime management. This is acceptable for typical view model lifetimes but may cause leaks in long-lived command instances.
- **No async support**: `Execute` is synchronous; asynchronous operations require manual wrapping (e.g., `async void` or fire-and-forget), which is error-prone.