--- 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 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()` 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.