init
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
---
|
||||
source_files:
|
||||
- Common/DTS.Common/Classes/DTS.Viewer/Commands/RelayCommand.cs
|
||||
generated_at: "2026-04-16T03:19:06.518329+00:00"
|
||||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||||
schema_version: 1
|
||||
sha256: "33db5b96b73a6f00"
|
||||
---
|
||||
|
||||
# Commands
|
||||
|
||||
### 1. **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 supports optional conditional execution via a `CanExecute` predicate and integrates with WPF’s `CommandManager` to automatically re-evaluate command availability when UI state changes (e.g., focus or selection changes). Its role is to serve as a lightweight, standard command implementation for MVVM pattern adoption, avoiding boilerplate command classes per action.
|
||||
|
||||
---
|
||||
|
||||
### 2. **Public Interface**
|
||||
- **`RelayCommand(Action<object> execute)`**
|
||||
Constructor. Initializes the command with an execution delegate and no `CanExecute` predicate (i.e., always executable).
|
||||
- Throws `ArgumentNullException` if `execute` is `null`.
|
||||
|
||||
- **`RelayCommand(Action<object> execute, Predicate<object> canExecute)`**
|
||||
Constructor. Initializes the command with both execution and availability predicates.
|
||||
- Throws `ArgumentNullException` if `execute` is `null`.
|
||||
- `canExecute` may be `null`, in which case the command is always executable.
|
||||
|
||||
- **`bool CanExecute(object parameter)`**
|
||||
Implements `ICommand.CanExecute`. Returns `true` if `_canExecute` is `null` or if `_canExecute(parameter)` returns `true`; otherwise `false`.
|
||||
|
||||
- **`event EventHandler CanExecuteChanged`**
|
||||
Implements `ICommand.CanExecuteChanged`. Subscribes/unsubscribes to `CommandManager.RequerySuggested`, triggering WPF to re-query `CanExecute` when system events (e.g., keyboard/mouse input, focus changes) occur.
|
||||
|
||||
- **`void Execute(object parameter)`**
|
||||
Implements `ICommand.Execute`. Invokes `_execute(parameter)`. No validation or exception handling is performed; exceptions propagate to the caller.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Invariants**
|
||||
- `_execute` is **never `null`** after construction (enforced via `ArgumentNullException` in both constructors).
|
||||
- `_canExecute` may be `null`; in this case, `CanExecute` always returns `true`.
|
||||
- `CanExecuteChanged` events are **always** routed to `CommandManager.RequerySuggested`; no custom event storage is used.
|
||||
- `Execute` and `CanExecute` are called with the same `parameter` value provided by the command source (e.g., `Button.CommandParameter`).
|
||||
|
||||
---
|
||||
|
||||
### 4. **Dependencies**
|
||||
- **Dependencies on external modules**:
|
||||
- `System` (for `Action<T>`, `Predicate<T>`, `ArgumentNullException`)
|
||||
- `System.Windows.Input` (for `ICommand`, `CommandManager`)
|
||||
- **Dependencies on other modules in the codebase**: None (no internal `using` statements beyond standard libraries).
|
||||
- **Depended upon by**: Presumably UI components (e.g., `Button`, `MenuItem`) in WPF views that bind commands via MVVM. Not visible in this file, but inferred from `ICommand` usage.
|
||||
|
||||
---
|
||||
|
||||
### 5. **Gotchas**
|
||||
- **No manual `CanExecuteChanged` raising**: Since `CanExecuteChanged` is wired to `CommandManager.RequerySuggested`, the command’s executability is only re-evaluated on `CommandManager`-triggered events (e.g., user input). If the command’s availability depends on non-UI state (e.g., background task completion), `CommandManager.InvalidateRequerySuggested()` must be called externally to force re-evaluation.
|
||||
- **No parameter validation**: `Execute` passes the `parameter` directly to `_execute` without null-checking or type validation. If `_execute` expects a specific type (e.g., `string`), passing an incompatible type will cause a runtime exception.
|
||||
- **Thread affinity**: `Execute` runs on the calling thread (typically the UI thread), but no thread-safety guarantees are provided. If invoked from a background thread, UI updates inside `_execute` will fail.
|
||||
- **Memory leak risk**: If subscribers to `CanExecuteChanged` are not properly disposed, the `CommandManager` may hold references indefinitely (though this is a general WPF pattern risk, not unique to this class).
|
||||
|
||||
None identified beyond the above.
|
||||
Reference in New Issue
Block a user