283 lines
15 KiB
Markdown
283 lines
15 KiB
Markdown
|
|
---
|
||
|
|
source_files:
|
||
|
|
- Common/DTS.Common/Controls/RoundedBox.xaml.cs
|
||
|
|
- Common/DTS.Common/Controls/TestIDView.xaml.cs
|
||
|
|
- Common/DTS.Common/Controls/checkbox.xaml.cs
|
||
|
|
- Common/DTS.Common/Controls/GridLengthAnimation.cs
|
||
|
|
- Common/DTS.Common/Controls/ISOPopup.xaml.cs
|
||
|
|
- Common/DTS.Common/Controls/LookupPopup.xaml.cs
|
||
|
|
- Common/DTS.Common/Controls/TestIdPreFixSuffixHelper.cs
|
||
|
|
- Common/DTS.Common/Controls/AutoSizedGridView.cs
|
||
|
|
- Common/DTS.Common/Controls/TestIDTestBox.xaml.cs
|
||
|
|
- Common/DTS.Common/Controls/DynamicGrid.cs
|
||
|
|
- Common/DTS.Common/Controls/TestIDViewModel.cs
|
||
|
|
- Common/DTS.Common/Controls/TestIDControl.xaml.cs
|
||
|
|
- Common/DTS.Common/Controls/GridViewColumnHeaderSelectable.xaml.cs
|
||
|
|
- Common/DTS.Common/Controls/IPTextBox.xaml.cs
|
||
|
|
- Common/DTS.Common/Controls/GridViewColumnHeaderSearchable.xaml.cs
|
||
|
|
generated_at: "2026-04-17T15:28:10.757079+00:00"
|
||
|
|
model: "zai-org/GLM-5-FP8"
|
||
|
|
schema_version: 1
|
||
|
|
sha256: "6f3f540e08a3809f"
|
||
|
|
---
|
||
|
|
|
||
|
|
# DTS.Common.Controls Documentation
|
||
|
|
|
||
|
|
## 1. Purpose
|
||
|
|
|
||
|
|
The `DTS.Common.Controls` namespace provides a collection of custom WPF controls and helper classes for the DTS application. It includes specialized input controls (IP address entry, test ID input), animated grid components, popup dialogs for lookups and ISO entry, dynamic layout containers, and enhanced GridView column headers with search and selection capabilities. The module serves as a reusable UI component library supporting data entry validation, event-driven communication via Prism's EventAggregator, and MVVM-compatible bindable controls.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. Public Interface
|
||
|
|
|
||
|
|
### RoundedBox
|
||
|
|
```csharp
|
||
|
|
public partial class RoundedBox : UserControl
|
||
|
|
public RoundedBox()
|
||
|
|
public void Connect(int connectionId, object target)
|
||
|
|
```
|
||
|
|
A simple UserControl. The `Connect` method is defined but contains commented-out code and effectively does nothing.
|
||
|
|
|
||
|
|
### TestIDView
|
||
|
|
```csharp
|
||
|
|
public partial class TestIDView : UserControl
|
||
|
|
public TestIDView()
|
||
|
|
```
|
||
|
|
A simple UserControl with no additional public members beyond the constructor.
|
||
|
|
|
||
|
|
### checkbox
|
||
|
|
```csharp
|
||
|
|
public partial class checkbox
|
||
|
|
public void ToolTipEventHandler(object sender, ToolTipEventArgs e)
|
||
|
|
```
|
||
|
|
Handles tooltip events by marking them handled and publishing a `HelpTextEvent` via the `IEventAggregator`.
|
||
|
|
|
||
|
|
### GridLengthAnimation
|
||
|
|
```csharp
|
||
|
|
public class GridLengthAnimation : AnimationTimeline
|
||
|
|
public GridLengthAnimation()
|
||
|
|
public GridLength From { get; set; } // DependencyProperty
|
||
|
|
public GridLength To { get; set; } // DependencyProperty
|
||
|
|
public override Type TargetPropertyType { get; } // Returns typeof(GridLength)
|
||
|
|
public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)
|
||
|
|
protected override Freezable CreateInstanceCore()
|
||
|
|
```
|
||
|
|
Custom animation timeline for animating `GridLength` values. Supports both `Star` and `Pixel` unit types based on the `To` value.
|
||
|
|
|
||
|
|
### ISOPopup
|
||
|
|
```csharp
|
||
|
|
public partial class ISOPopup : Popup
|
||
|
|
public ISOPopup()
|
||
|
|
```
|
||
|
|
A Popup control with private event handlers (`ISOPart_OnPreviewKeyUp`, `ISOPart_OnGotMouseCapture`, `ISOPart_OnGotKeyboardFocus`) that restrict input to alphanumeric characters and select all text on focus.
|
||
|
|
|
||
|
|
### LookupPopup
|
||
|
|
```csharp
|
||
|
|
public partial class LookupPopup : Popup
|
||
|
|
public LookupPopup()
|
||
|
|
public IEnumerable<IChannelCode> AllChannelCodes { get; private set; }
|
||
|
|
public IList PossibleChannels { get; set; } // DependencyProperty
|
||
|
|
public delegate void ChannelCodeSelectedEventHandler(object sender, string code, string name)
|
||
|
|
public event ChannelCodeSelectedEventHandler ChannelCodeSelected
|
||
|
|
```
|
||
|
|
A Popup for selecting channel codes from a DataGrid. Raises `ChannelCodeSelected` event on double-click with `Code` and `Name` properties extracted via reflection.
|
||
|
|
|
||
|
|
### TestIdPreFixSuffixHelper & Related Classes
|
||
|
|
```csharp
|
||
|
|
public enum TestIdFixedPrefixSuffixValues { NotFixed = -1, None = 0, TimeStamp = 1, TestSetupName = 2 }
|
||
|
|
|
||
|
|
public class TestIdPreFixSuffix
|
||
|
|
public TestIdPreFixSuffix(TestIdFixedPrefixSuffixValues fixedPrefixSuffix)
|
||
|
|
public TestIdPreFixSuffix(string dbPrefixSuffix)
|
||
|
|
public TestIdFixedPrefixSuffixValues FixedValue { get; }
|
||
|
|
public override string ToString()
|
||
|
|
|
||
|
|
public class TestIdPreFixSuffixHelper : BasePropertyChanged
|
||
|
|
public TestIdPreFixSuffixHelper(string testIdPreFixSuffix)
|
||
|
|
public TestIdPreFixSuffixHelper(TestIdFixedPrefixSuffixValues testIdPreFixSuffix)
|
||
|
|
public TestIdPreFixSuffix TestIdPreFixSuffix { get; }
|
||
|
|
public override string ToString()
|
||
|
|
public override bool Equals(object obj)
|
||
|
|
```
|
||
|
|
Helper classes for managing test ID prefix/suffix values with support for fixed types (None, TimeStamp, TestSetupName) and custom database values.
|
||
|
|
|
||
|
|
### AutoSizedGridView
|
||
|
|
```csharp
|
||
|
|
public class AutoSizedGridView : GridView
|
||
|
|
protected override void PrepareItem(ListViewItem item)
|
||
|
|
```
|
||
|
|
Custom GridView that tracks auto-width columns and width-bound columns, forcing re-measurement and re-binding as needed during item preparation.
|
||
|
|
|
||
|
|
### TestIDTextBox
|
||
|
|
```csharp
|
||
|
|
public partial class TestIDTextBox : UserControl
|
||
|
|
public TestIDTextBox()
|
||
|
|
public void Clear()
|
||
|
|
public string Text { get; set; } // DependencyProperty, two-way binding by default
|
||
|
|
```
|
||
|
|
A UserControl for test ID input that validates against invalid filename/path characters and the period character.
|
||
|
|
|
||
|
|
### DynamicGrid
|
||
|
|
```csharp
|
||
|
|
public class DynamicGrid : Grid, INotifyPropertyChanged
|
||
|
|
public DynamicGrid()
|
||
|
|
public byte GridColumns { get; set; } // Default: 2
|
||
|
|
public void Refresh()
|
||
|
|
public event PropertyChangedEventHandler PropertyChanged
|
||
|
|
```
|
||
|
|
A Grid that automatically arranges children in a specified number of columns. The last column uses `Star` sizing; others use `Auto`. Implements `INotifyPropertyChanged`.
|
||
|
|
|
||
|
|
### TestIDViewModel
|
||
|
|
```csharp
|
||
|
|
public class TestIDViewModel : INotifyPropertyChanged
|
||
|
|
public string TestSetupLabel { get; set; }
|
||
|
|
public Visibility TestSetupLabelVisibility { get; }
|
||
|
|
public string TestIdEditableText { get; set; }
|
||
|
|
public void PopulateAllTestIdPrefixSuffixValues(string[] serializedValues)
|
||
|
|
public TestIdPreFixSuffixHelper[] AllTestIdPrefixSuffixValues { get; }
|
||
|
|
public TestIdPreFixSuffixHelper SelectedTestIdPrefixValueItem { get; set; } // Default: None
|
||
|
|
public TestIdPreFixSuffixHelper SelectedTestIdSuffixValueItem { get; set; } // Default: TimeStamp
|
||
|
|
public string TestName { get; set; }
|
||
|
|
public string GetTestId()
|
||
|
|
public string GetTestIdTimestamp()
|
||
|
|
public event PropertyChangedEventHandler PropertyChanged
|
||
|
|
```
|
||
|
|
ViewModel for constructing test IDs from prefix, label, editable text, and suffix components.
|
||
|
|
|
||
|
|
### TestIdControl
|
||
|
|
```csharp
|
||
|
|
public partial class TestIdControl : UserControl, INotifyPropertyChanged
|
||
|
|
public TestIdControl()
|
||
|
|
public string TestSetupLabel { get; set; }
|
||
|
|
public Visibility TestSetupLabelVisibility { get; }
|
||
|
|
public string TestIdEditableText { get; set; }
|
||
|
|
public void PopulateAllTestIdPrefixSuffixValues(string[] serializedValues)
|
||
|
|
public TestIdPreFixSuffixHelper[] AllTestIdPrefixSuffixValues { get; }
|
||
|
|
public TestIdPreFixSuffixHelper SelectedTestIdPrefixValueItem { get; set; } // Default: None
|
||
|
|
public TestIdPreFixSuffixHelper SelectedTestIdSuffixValueItem { get; set; } // Default: TimeStamp
|
||
|
|
public string TestName { get; set; }
|
||
|
|
public string GetTestId()
|
||
|
|
public string GetTestIdTimestamp()
|
||
|
|
public event PropertyChangedEventHandler PropertyChanged
|
||
|
|
```
|
||
|
|
**Marked for removal** per source comment. Nearly identical to `TestIDViewModel` but as a UserControl. Intended to be removed after TTS module deletion and migration to new test setup wizard.
|
||
|
|
|
||
|
|
### GridViewColumnHeaderSelectable
|
||
|
|
```csharp
|
||
|
|
public partial class GridViewColumnHeaderSelectable : UserControl, IBasePropertyChanged
|
||
|
|
public GridViewColumnHeaderSelectable()
|
||
|
|
public string ListviewId { get; set; } // DependencyProperty
|
||
|
|
public string HeaderTitle { get; set; } // DependencyProperty, default: "Awesome"
|
||
|
|
public bool ToggleButtonIsChecked { get; set; } // DependencyProperty, default: false
|
||
|
|
public event RoutedEventHandler OpenChanged // Bubbling routed event
|
||
|
|
public event RoutedEventHandler ClickHandler // Bubbling routed event
|
||
|
|
public event RoutedEventHandler SelectAll // Bubbling routed event
|
||
|
|
public event PropertyChangedEventHandler PropertyChanged
|
||
|
|
public override string ToString()
|
||
|
|
```
|
||
|
|
A column header with a toggle button popup supporting select-all/clear-all functionality. Subscribes to `ListViewStatusEvent` for unload handling.
|
||
|
|
|
||
|
|
### IPTextBox
|
||
|
|
```csharp
|
||
|
|
public partial class IPTextBox : UserControl
|
||
|
|
public IPTextBox()
|
||
|
|
public void Clear()
|
||
|
|
public string Address { get; set; } // DependencyProperty, two-way binding by default
|
||
|
|
```
|
||
|
|
An IP address input control with four segments. Handles navigation between segments, digit-only input, period key for segment advancement, and paste validation.
|
||
|
|
|
||
|
|
### GridViewColumnHeaderSearchable
|
||
|
|
```csharp
|
||
|
|
public partial class GridViewColumnHeaderSearchable : UserControl, IBasePropertyChanged
|
||
|
|
public GridViewColumnHeaderSearchable()
|
||
|
|
public string ListviewId { get; set; } // DependencyProperty
|
||
|
|
public string HeaderTitle { get; set; } // DependencyProperty, default: "Awesome"
|
||
|
|
public string HeaderSearchTerm { get; set; } // DependencyProperty
|
||
|
|
public bool ToggleButtonIsChecked { get; set; } // DependencyProperty, default: false
|
||
|
|
public Geometry ToggleIconGeometry { get; }
|
||
|
|
public event RoutedEventHandler OpenChanged // Bubbling routed event
|
||
|
|
public event RoutedEventHandler ClickHandler // Bubbling routed event
|
||
|
|
public event RoutedEventHandler Search // Bubbling routed event
|
||
|
|
public event PropertyChangedEventHandler PropertyChanged
|
||
|
|
public override string ToString()
|
||
|
|
```
|
||
|
|
A searchable column header with a popup containing a search textbox. Raises `Search` event on term change. Subscribes to `ListViewStatusEvent` for unload handling.
|
||
|
|
|
||
|
|
### BoolToInvertedBoolConverter
|
||
|
|
```csharp
|
||
|
|
public class BoolToInvertedBoolConverter : IValueConverter
|
||
|
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||
|
|
public object ConvertBack(...) // Throws NotImplementedException
|
||
|
|
```
|
||
|
|
Value converter that inverts boolean values.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. Invariants
|
||
|
|
|
||
|
|
- **GridLengthAnimation**: The `To.IsStar` property determines the `GridUnitType` of the resulting `GridLength` in `GetCurrentValue()`. The animation direction (expanding vs. collapsing) is determined by comparing `From.Value` to `To.Value`.
|
||
|
|
|
||
|
|
- **ISOPopup**: Input is restricted to A-Z, 0-9 (both main keyboard and numpad), and control keys (Enter, Return, Tab, OemBackTab, Delete, Back, Home, End, OemQuestion). All other keys are handled (suppressed).
|
||
|
|
|
||
|
|
- **LookupPopup**: The `PossibleChannels` list items must have `Code` and `Name` properties accessible via reflection for the `ChannelCodeSelected` event to function correctly.
|
||
|
|
|
||
|
|
- **TestIDTextBox**: Text cannot contain invalid filename characters, invalid path characters, or periods (`.`). The `Text` property binds two-way by default.
|
||
|
|
|
||
|
|
- **IPTextBox**: Each segment accepts up to 3 digits. The `Address` property format is `{0}.{1}.{2}.{3}`. The control automatically advances focus when a segment reaches 3 characters or period is pressed.
|
||
|
|
|
||
|
|
- **DynamicGrid**: `GridColumns` must be a `byte` value. The last column always uses `GridUnitType.Star`; all preceding columns use `GridUnitType.Auto`. An extra row with `Star` height is always added at the end.
|
||
|
|
|
||
|
|
- **TestIdPreFixSuffixHelper.Equals()**: Two instances are equal if their `FixedValue` properties match and are not `NotFixed`, OR if `FixedValue` is `NotFixed` and their string representations match.
|
||
|
|
|
||
|
|
- **GridViewColumnHeaderSelectable/GridViewColumnHeaderSearchable**: The `HeaderTitle` default value is `"Awesome"`. These controls require a resolved `IEventAggregator` from `ContainerLocator.Container` at construction time.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. Dependencies
|
||
|
|
|
||
|
|
### External Dependencies (Imports)
|
||
|
|
- **System.Windows.Controls** - Base UserControl, GridView, ListView, Popup, TextBox, DataGrid
|
||
|
|
- **System.Windows** - DependencyObject, DependencyPropertyChangedEventArgs, FrameworkPropertyMetadata, GridLength, GridUnitType, Visibility, RoutedEvent, EventManager
|
||
|
|
- **System.Windows.Input** - Key, KeyEventArgs, KeyboardFocusChangedEventArgs, MouseButtonEventArgs, ModifierKeys, TraversalRequest, FocusManager
|
||
|
|
- **System.Windows.Media.Animation** - AnimationTimeline, AnimationClock
|
||
|
|
- **System.Windows.Data** - BindingExpression, BindingOperations, IValueConverter
|
||
|
|
- **System.Windows.Controls.Primitives** - Popup base class
|
||
|
|
- **System.ComponentModel** - INotifyPropertyChanged, PropertyChangedEventArgs
|
||
|
|
- **System.IO** - Path (for invalid character validation)
|
||
|
|
- **Prism.Ioc** - ContainerLocator
|
||
|
|
- **Prism.Events** - IEventAggregator, ThreadOption, PubSubEvent
|
||
|
|
|
||
|
|
### Internal Dependencies
|
||
|
|
- **DTS.Common.Events** - `HelpTextEvent`, `HelpTextEventArg`, `ListViewStatusEvent`, `ListViewStatusArg`
|
||
|
|
- **DTS.Common.Base** - `BasePropertyChanged`, `IBasePropertyChanged`
|
||
|
|
- **DTS.Common.Interface.Channels.ChannelCodes** - `IChannelCode`
|
||
|
|
- **DTS.Common.Utilities.Logging** - Referenced in `GridViewColumnHeaderSelectable` and `GridViewColumnHeaderSearchable` (usage not visible in provided source)
|
||
|
|
- **Strings.Strings** - ResourceManager for localized strings in `TestIdPreFixSuffixHelper.ToString()`
|
||
|
|
|
||
|
|
### Consumers
|
||
|
|
- Unknown from source alone. The controls are designed for consumption by other modules in the DTS application.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. Gotchas
|
||
|
|
|
||
|
|
1. **TestIdControl is deprecated**: The source explicitly states: *"Remove this control after deleting the TTS module and migrating to new test setup wizard"*. New code should use `TestIDViewModel` instead.
|
||
|
|
|
||
|
|
2. **checkbox naming convention**: The `checkbox` class violates C# naming conventions (should be PascalCase `CheckBox`). This may cause confusion with `System.Windows.Controls.CheckBox`.
|
||
|
|
|
||
|
|
3. **RoundedBox.Connect is non-functional**: The method body is commented out with `//throw new System.NotImplementedException();`. It's unclear why this method exists.
|
||
|
|
|
||
|
|
4. **LookupPopup uses reflection**: The `PossibleChannels_OnMouseDoubleClick` handler uses `GetProperty("Code")` and `GetProperty("Name")` via reflection rather than casting to a known interface. This is fragile and will fail silently (return null) if properties don't exist.
|
||
|
|
|
||
|
|
5. **GridViewColumnHeaderSelectable/GridViewColumnHeaderSearchable require Prism container at construction**: These controls call `ContainerLocator.Container.Resolve<IEventAggregator>()` in their constructors. If the container is not available or not configured, this will throw.
|
||
|
|
|
||
|
|
6. **IPTextBox.Clear() does not update Address**: The `Clear()` method sets segment text to empty but does not trigger the `Address` property update (no `_suppressAddressUpdate` handling).
|
||
|
|
|
||
|
|
7. **TestIDTextBox validation allows empty strings**: `IsValidText("")` returns `true` since no invalid characters are present.
|
||
|
|
|
||
|
|
8. **GridLengthAnimation.GetCurrentValue() assumes CurrentProgress has value**: Accesses `animationClock.CurrentProgress.Value` without null checking `CurrentProgress`. May throw if progress is unavailable.
|
||
|
|
|
||
|
|
9. **DynamicGrid.Refresh() clears and rebuilds all definitions**: Called on every `GridColumns` change and every `OnVisualChildrenChanged`. This could be expensive for grids with many children.
|
||
|
|
|
||
|
|
10. **BoolToInvertedBoolConverter.ConvertBack throws**: Explicitly throws `NotImplementedException`. Do not use in two-way bindings expecting conversion back.
|