init
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
---
|
||||
source_files:
|
||||
- DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/Classes/VirtualToggleButton.cs
|
||||
generated_at: "2026-04-16T13:48:16.790928+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "001b39a3411ec3ba"
|
||||
---
|
||||
|
||||
# Documentation: VirtualToggleButton
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
`VirtualToggleButton` is a static helper class that provides attached dependency properties to imbue any WPF element with toggle button behavior. Rather than requiring inheritance from `ToggleButton`, this module allows arbitrary `DependencyObject` instances (specifically those implementing `IInputElement`) to respond to mouse clicks and keyboard input (Space/Enter) by toggling between checked, unchecked, and optionally indeterminate states. This is used within the `DTS.Viewer.GraphList` module to create toggle-style interactions on elements that cannot directly inherit from `ToggleButton`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Attached Properties
|
||||
|
||||
#### `IsLockedProperty`
|
||||
- **Type:** `DependencyProperty` (attached)
|
||||
- **Value Type:** `Nullable<bool>`
|
||||
- **Default Value:** `false`
|
||||
- **Metadata Flags:** `BindsTwoWayByDefault | Journal`
|
||||
- **Get Accessor:** `Nullable<bool> GetIsLocked(DependencyObject d)`
|
||||
- **Set Accessor:** `void SetIsLocked(DependencyObject d, Nullable<bool> value)`
|
||||
- **Behavior:** Represents the toggle state. When changed, raises `ToggleButton.CheckedEvent` (if `true`), `ToggleButton.UncheckedEvent` (if `false`), or `ToggleButton.IndeterminateEvent` (if `null`).
|
||||
|
||||
#### `IsThreeStateProperty`
|
||||
- **Type:** `DependencyProperty` (attached)
|
||||
- **Value Type:** `bool`
|
||||
- **Default Value:** `false`
|
||||
- **Get Accessor:** `bool GetIsThreeState(DependencyObject d)`
|
||||
- **Set Accessor:** `void SetIsThreeState(DependencyObject d, bool value)`
|
||||
- **Behavior:** When `true`, allows `IsLocked` to cycle through `null` (indeterminate) state during toggle operations.
|
||||
|
||||
#### `IsVirtualToggleButtonProperty`
|
||||
- **Type:** `DependencyProperty` (attached)
|
||||
- **Value Type:** `bool`
|
||||
- **Default Value:** `false`
|
||||
- **Get Accessor:** `bool GetIsVirtualToggleButton(DependencyObject d)`
|
||||
- **Set Accessor:** `void SetIsVirtualToggleButton(DependencyObject d, bool value)`
|
||||
- **Behavior:** When set to `true` on an `IInputElement`, subscribes `OnMouseLeftButtonDown` and `OnKeyDown` handlers. When set to `false`, unsubscribes them.
|
||||
|
||||
### Internal Methods
|
||||
|
||||
#### `RaiseCheckedEvent(UIElement target)`
|
||||
- **Returns:** `RoutedEventArgs` or `null` if target is null
|
||||
- **Behavior:** Raises `ToggleButton.CheckedEvent` on the target element.
|
||||
|
||||
#### `RaiseUncheckedEvent(UIElement target)`
|
||||
- **Returns:** `RoutedEventArgs` or `null` if target is null
|
||||
- **Behavior:** Raises `ToggleButton.UncheckedEvent` on the target element.
|
||||
|
||||
#### `RaiseIndeterminateEvent(UIElement target)`
|
||||
- **Returns:** `RoutedEventArgs` or `null` if target is null
|
||||
- **Behavior:** Raises `ToggleButton.IndeterminateEvent` on the target element.
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
1. **Input Handler Attachment:** Setting `IsVirtualToggleButton` to `true` on a non-`IInputElement` has no effect (handlers are not attached, no exception is thrown).
|
||||
|
||||
2. **Toggle State Cycling Logic (in `UpdateIsLocked`):**
|
||||
- If `IsLocked == true`: Sets to `false`, or `null` if `IsThreeState` is `true`.
|
||||
- If `IsLocked == false` or `null`: Sets to `true`.
|
||||
|
||||
3. **Keyboard Handling:**
|
||||
- `Space` key toggles the state, unless `Alt` modifier is present (system menu invocation is preserved).
|
||||
- `Enter` key toggles the state only if `KeyboardNavigation.AcceptsReturnProperty` is `true` on the sender.
|
||||
|
||||
4. **Event Routing:** Raised events use `ToggleButton.CheckedEvent`, `ToggleButton.UncheckedEvent`, and `ToggleButton.IndeterminateEvent` as routed event identifiers.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This Module Depends On:
|
||||
- `System`
|
||||
- `System.Windows` (`DependencyObject`, `DependencyProperty`, `FrameworkPropertyMetadata`, `UIElement`, `ContentElement`, `RoutedEventArgs`, `IInputElement`)
|
||||
- `System.Windows.Controls.Primitives` (`ToggleButton`)
|
||||
- `System.Windows.Input` (`Key`, `KeyEventArgs`, `Keyboard`, `KeyboardNavigation`, `ModifierKeys`, `MouseButtonEventArgs`)
|
||||
|
||||
### Consumers:
|
||||
- Unclear from source alone. The class is in `DTS.Viewer.GraphList` namespace, suggesting consumption by GraphList-related components.
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **Misleading XML Documentation:** The XML comments for `IsLocked` state "indicates whether the toggle button is checked" — this appears to be copy-pasted from a standard `IsChecked` property. The property name `IsLocked` suggests a different semantic meaning (possibly "locked/selected" in the context of graph items).
|
||||
|
||||
2. **Type Inconsistency in Event Raising:** The private `RaiseEvent` method supports both `UIElement` and `ContentElement`, but the internal `RaiseCheckedEvent`, `RaiseUncheckedEvent`, and `RaiseIndeterminateEvent` methods only accept `UIElement`. If a `ContentElement` needs these events raised, the internal methods cannot be used directly.
|
||||
|
||||
3. **Namespace Suppression:** The file contains `// ReSharper disable CheckNamespace`, indicating the namespace `DTS.Viewer.GraphList` may not match the project's default namespace structure. This could indicate a refactoring artifact or intentional namespace override.
|
||||
|
||||
4. **No Null Guard in `UpdateIsLocked`:** The method casts `sender as DependencyObject` without null-checking before calling `GetIsLocked(d)`. If called with a non-`DependencyObject` sender, this would pass null to `GetIsLocked`, which would throw a `NullReferenceException` inside `d.GetValue()`.
|
||||
|
||||
5. **Event Handled Flag:** Both `OnMouseLeftButtonDown` and `OnKeyDown` mark events as `e.Handled = true`, which may prevent bubbling to parent handlers unexpectedly.
|
||||
Reference in New Issue
Block a user