79 lines
7.8 KiB
Markdown
79 lines
7.8 KiB
Markdown
|
|
---
|
|||
|
|
source_files:
|
|||
|
|
- DataPRO/Modules/ISO/ExtraProperties/View/ExtraPropertiesListView.xaml.cs
|
|||
|
|
generated_at: "2026-04-16T04:39:06.939358+00:00"
|
|||
|
|
model: "Qwen/Qwen3-Coder-Next-FP8"
|
|||
|
|
schema_version: 1
|
|||
|
|
sha256: "35a6fb72ede64411"
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# View
|
|||
|
|
|
|||
|
|
## Documentation: `ExtraPropertiesListView` Module
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### **1. Purpose**
|
|||
|
|
|
|||
|
|
`ExtraPropertiesListView` is a WPF user control implementing the `IExtraPropertiesListView` interface to render and interact with a list of extra properties (key-value pairs) in the ISO module. It serves as the view layer in a MVVM pattern, handling UI events (sorting, filtering, selection, editing) and delegating logic to its bound `IExtraPropertiesListViewModel`. The control supports interactive column sorting (via header clicks or text clicks), filtering by column tag, real-time validation and modification tracking during inline editing of property keys and values, and selection synchronization with the view model.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### **2. Public Interface**
|
|||
|
|
|
|||
|
|
The class itself is `public partial class ExtraPropertiesListView : IExtraPropertiesListView`. It exposes no *public* methods or properties beyond those defined by the interface `IExtraPropertiesListView` (not shown in source), but its *event handlers* are the primary public-facing behavior surface. All handlers are private `RoutedEventHandler` or `KeyEventHandler` methods wired via XAML (not visible here, but implied by naming and usage).
|
|||
|
|
|
|||
|
|
| Member | Signature | Behavior |
|
|||
|
|
|--------|-----------|----------|
|
|||
|
|
| `ExtraPropertiesListView()` | `public ExtraPropertiesListView()` | Constructor; calls `InitializeComponent()` to load the associated XAML. |
|
|||
|
|
| `GridViewColumnHeaderSearchable_OnSearch` | `private void GridViewColumnHeaderSearchable_OnSearch(object sender, RoutedEventArgs e)` | Extracts `searchTerm` from `e.OriginalSource` and `columnTag` from the `Tag` of the `GridViewColumnHeaderSearchable` sender, then invokes `viewModel.Filter(columnTag, searchTerm)`. |
|
|||
|
|
| `GridViewColumnHeader_OnClick` | `private void GridViewColumnHeader_OnClick(object sender, RoutedEventArgs e)` | Extracts `columnTag` from the `Tag` of the `GridViewColumnHeaderSearchable` sender (or via `Utils.FindChild`), then invokes `vm?.Sort(columnTag, true)`. |
|
|||
|
|
| `ExtraPropertyKeyTextBox_KeyDown` | `private void ExtraPropertyKeyTextBox_KeyDown(object sender, KeyEventArgs e)` | If `DataContext` is `ExtraPropertiesListViewModel` and the `TextBox`’s `DataContext` is `IExtraProperty`, calls `vm.MarkModified(iep)`. |
|
|||
|
|
| `ExtraPropertyKeyTextBox_TextChanged` | `private void ExtraPropertyKeyTextBox_TextChanged(object sender, TextChangedEventArgs e)` | Same context checks as above; calls `vm.MarkModified(iep)` and then `vm.Validate(ref notUsed1, ref notUsed2)` (with unused `List<string>` parameters). |
|
|||
|
|
| `ExtraPropertyValueTextBox_KeyDown` | `private void ExtraPropertyValueTextBox_KeyDown(object sender, KeyEventArgs e)` | Same as `ExtraPropertyKeyTextBox_KeyDown`; calls `vm.MarkModified(iep)`. |
|
|||
|
|
| `ExtraPropertyValueTextBox_TextChanged` | `private void ExtraPropertyValueTextBox_TextChanged(object sender, TextChangedEventArgs e)` | Same as `ExtraPropertyKeyTextBox_TextChanged`; calls `vm.MarkModified(iep)` and `vm.Validate(...)`. |
|
|||
|
|
| `ExtraProperties_SelectionChanged` | `private void ExtraProperties_SelectionChanged(object sender, SelectionChangedEventArgs e)` | Collects selected `IExtraProperty` items from the `ListView`, then calls `vm.SetSelection(...)` with the array. |
|
|||
|
|
| `ExtraPropertiesListView_PreviewMouseLeftButtonUp` | `private void ExtraPropertiesListView_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)` | Performs hit-testing to detect clicks on column headers (`TextBlock`, `KeyColumnHeader`, or `ValueColumnHeader`) or descendants; if detected, calls `vm?.Sort(tag, true)` for the corresponding column. Also returns early if the click is on a `ScrollViewer`. |
|
|||
|
|
|
|||
|
|
> **Note**: Column header tags (`KeyColumnHeader.Tag`, `ValueColumnHeader.Tag`) are used as sort keys. Their values are assumed to be strings (e.g., `"Key"`, `"Value"`), inferred from usage in `PreviewMouseLeftButtonUp`.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### **3. Invariants**
|
|||
|
|
|
|||
|
|
- **DataContext Contract**: The `DataContext` must implement `IExtraPropertiesListViewModel` (or be `ExtraPropertiesListViewModel`, a concrete implementation). All event handlers cast `DataContext` to this interface or concrete type before use.
|
|||
|
|
- **Item Type Contract**: Selected items in the `ListView` and `TextBox.DataContext` items must be of type `IExtraProperty`. Non-conforming items are silently skipped in `ExtraProperties_SelectionChanged`.
|
|||
|
|
- **Validation Side Effect**: Every `TextChanged` event on key/value `TextBox`es triggers `vm.Validate(...)`, regardless of whether the text actually changed meaningfully.
|
|||
|
|
- **Sorting Trigger**: Sorting is *always* invoked with `ascending: true` (hardcoded), regardless of previous sort state or direction.
|
|||
|
|
- **Hit-Test Robustness**: The `PreviewMouseLeftButtonUp` handler performs multiple hit-tests (visual tree + input hit-test) to reliably detect clicks on headers despite nested visual elements (e.g., `Border`, `Rectangle`).
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### **4. Dependencies**
|
|||
|
|
|
|||
|
|
#### **External Dependencies (from imports)**:
|
|||
|
|
- `System.Collections.Generic`, `System.Windows.*`: Standard WPF and .NET types.
|
|||
|
|
- `DTS.Common.Controls`: Contains `GridViewColumnHeaderSearchable` (custom control used for searchable column headers).
|
|||
|
|
- `DTS.Common.Interface.ISO.ExtraProperties`: Defines `IExtraPropertiesListView`, `IExtraPropertiesListViewModel`, and `IExtraProperty`.
|
|||
|
|
- `DTS.Common.Utils`: Provides `Utils.FindChild<T>` (used in `GridViewColumnHeader_OnClick` to locate `Tag` from nested elements).
|
|||
|
|
|
|||
|
|
#### **Internal Dependencies**:
|
|||
|
|
- `ExtraProperties.Resources.StringResources`: Used for localized strings `"Key"` and `"Value"` (in `PreviewMouseLeftButtonUp`).
|
|||
|
|
- `ExtraPropertiesListView.xaml`: The associated XAML file (not shown), which defines `ExtraPropertiesListViewLV`, `KeyColumnHeader`, `ValueColumnHeader`, and event bindings.
|
|||
|
|
|
|||
|
|
#### **Depended Upon By**:
|
|||
|
|
- The module likely binds this view to an `ExtraPropertiesListViewModel` instance (or similar) via `DataContext`. No direct callers are visible, but the interface `IExtraPropertiesListView` implies integration into a larger ISO module UI.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### **5. Gotchas**
|
|||
|
|
|
|||
|
|
- **Unused `Validate` Parameters**: Both `TextChanged` handlers call `vm.Validate(ref notUsed1, ref notUsed2)` with newly allocated, unused `List<string>` variables. This suggests either incomplete validation reporting or legacy code where validation errors are ignored by the view.
|
|||
|
|
- **Hardcoded Sort Direction**: `vm.Sort(..., true)` is called unconditionally with `ascending: true`. No logic exists to toggle sort direction (e.g., on repeated clicks), which may confuse users expecting standard UI behavior.
|
|||
|
|
- **Redundant Hit-Testing**: The `PreviewMouseLeftButtonUp` handler performs two hit-tests (`VisualTreeHelper.HitTest` and `InputHitTest`) and checks multiple element types (`TextBlock`, `UIElement`, `ScrollViewer`, `KeyColumnHeader`, `ValueColumnHeader`). This complexity hints at prior instability in click detection.
|
|||
|
|
- **Assumed `Tag` Type**: `columnTag` is used directly as a sort key in `vm.Sort(columnTag, ...)`. Its type is inferred from usage (likely `string`), but not enforced or documented in the source.
|
|||
|
|
- **No Null Safety for `vm`**: Multiple calls use `vm?.Sort(...)` or `vm?.Filter(...)`, but `vm.MarkModified(...)` and `vm.SetSelection(...)` do *not* use null-conditional operators. If `DataContext` is null or wrong type, these will throw.
|
|||
|
|
- **`KeyDown` vs `TextChanged` Duplication**: Both `KeyDown` and `TextChanged` handlers call `MarkModified` and `Validate`. This may cause redundant work or validation flicker if both events fire for a single edit (e.g., typing + Enter).
|
|||
|
|
|
|||
|
|
> **None identified from source alone.**
|
|||
|
|
*(Note: While several potential issues are noted above, they are inferred from code structure and behavior—not documented quirks.)*
|