init
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/Modules/Groups/GroupChannelList/Converters/BooleanToWidthConverter.cs
|
||||
- DataPRO/Modules/Groups/GroupChannelList/Converters/SensorIdBackgroundConverter.cs
|
||||
generated_at: "2026-04-17T16:13:20.076259+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "e25d08690ef1d9de"
|
||||
---
|
||||
|
||||
# Converters
|
||||
|
||||
### Purpose
|
||||
This module provides WPF value converters for the `GroupChannelList` UI component. It exists to transform data values into visual representations in XAML bindings, specifically converting boolean values to width measurements and background brush colors for sensor ID display elements.
|
||||
|
||||
### Public Interface
|
||||
- **`BooleanToWidthConverter` class** (public) - Implements `IValueConverter`. Converts boolean values to width values for UI element sizing.
|
||||
- `object Convert(object value, Type targetType, object parameter, CultureInfo culture)` - Returns `width` (parsed from parameter) if `value` is `true`, returns `0` if `value` is `false`, returns `0` if `value` is `null`. If parameter parsing fails, returns `double.NaN`.
|
||||
- `object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)` - Throws `NotImplementedException`.
|
||||
|
||||
- **`SensorIdBackgroundConverter` class** (public) - Implements `IValueConverter`. Converts boolean values to background brush colors.
|
||||
- `object Convert(object value, Type targetType, object parameter, CultureInfo culture)` - Returns a light green brush (`#FFE3FBE1`) if `value` is `true`, returns `Brushes.Transparent` if `value` is `false` or `null`. Catches and traces exceptions.
|
||||
- `object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)` - Throws `NotImplementedException`.
|
||||
|
||||
### Invariants
|
||||
- `ConvertBack` is not implemented on either converter; these are one-way converters only.
|
||||
- `SensorIdBackgroundConverter.SensorIdBrush` is a static field that is frozen before return to make it thread-safe and non-modifiable.
|
||||
|
||||
### Dependencies
|
||||
- **Depends on**: `System.Windows.Data.IValueConverter`, `System.Windows.Media.SolidColorBrush`, `System.Windows.Media.Color`, `System.Windows.Media.Brushes`, `System.Globalization.CultureInfo`, `System.Diagnostics.Trace`.
|
||||
- **Depended on by**: XAML views in the `GroupChannelList
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/Modules/Groups/GroupChannelList/Properties/Settings.Designer.cs
|
||||
- DataPRO/Modules/Groups/GroupChannelList/Properties/AssemblyInfo.cs
|
||||
generated_at: "2026-04-17T16:13:20.076523+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "db9235aae8cb1ff1"
|
||||
---
|
||||
|
||||
# Properties
|
||||
|
||||
### Purpose
|
||||
This module provides assembly metadata and application-scoped configuration settings for the `RegAddProductCode` custom installer action. It exists to configure Windows Installer policy-related registry operations, specifically for managing secure repair whitelisting. The settings defined here are used during installation to register product codes that allow the application to be repaired without elevated privileges.
|
||||
|
||||
### Public Interface
|
||||
- **`Settings` class** (internal sealed, partial) - Auto-generated settings class inheriting from `System.Configuration.ApplicationSettingsBase`.
|
||||
- `static Settings Default { get; }` - Returns the synchronized singleton instance of settings.
|
||||
- `string InstallerKey { get; }` - Returns `"SOFTWARE\\Policies\\Microsoft\\Windows\\Installer"`. Application-scoped setting.
|
||||
- `string MissingKey { get; }` - Returns `"No key at {0}"`. Format string template for missing key messages. Application-scoped setting.
|
||||
- `string ProductCode { get; }` - Returns `"{C4889149-0CAF-44C1-B226-8F6E73684DF4}"`. The GUID product code for this product. Application-scoped setting.
|
||||
- `string SecureRepairPolicy { get; }` - Returns `"SecureRepairPolicy"`. Application-scoped setting.
|
||||
- `string SecureRepairWhitelistKey { get; }` - Returns `"SOFTWARE\\Policies\\Microsoft\\Windows\\Installer\\SecureRepairWhitelist"`. Application-scoped setting.
|
||||
|
||||
### Invariants
|
||||
- All settings are application-scoped and read-only at runtime.
|
||||
- The `ProductCode` GUID must be a valid Windows Installer product code format.
|
||||
- Registry key paths use double backslash escaping for .NET string literals.
|
||||
|
||||
### Dependencies
|
||||
- **Depends on**: `System.Configuration.ApplicationSettingsBase`, `System.Runtime.CompilerServices`, `System.Runtime.InteropServices`.
|
||||
- **Depended on by**: The parent `RegAddProductCode` installer custom action module (inferred from namespace).
|
||||
|
||||
### Gotchas
|
||||
- The `MissingKey` setting contains a format placeholder `{0}` suggesting it's intended for `string.Format()` usage, but the consuming code is not visible in this module.
|
||||
- The `ProductCode` GUID `{C4889149-0CAF-44C1-B226-8F6E73684DF4}` is hardcoded; if the actual product code changes, this setting must be updated manually.
|
||||
|
||||
---
|
||||
216
docs/ai/DataPRO/Modules/Groups/GroupChannelList/Resources.md
Normal file
216
docs/ai/DataPRO/Modules/Groups/GroupChannelList/Resources.md
Normal file
@@ -0,0 +1,216 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/Modules/Groups/GroupChannelList/Resources/TranslateExtension.cs
|
||||
- DataPRO/Modules/Groups/GroupChannelList/Resources/StringResources.Designer.cs
|
||||
generated_at: "2026-04-17T15:58:50.253166+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "fc71a9ad19b8ef2b"
|
||||
---
|
||||
|
||||
# Documentation: GroupChannelList Resources Module
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
This module provides localization infrastructure for the GroupChannelList feature within the DataPRO Groups module. It consists of a WPF XAML markup extension (`TranslateExtension`) that enables declarative string localization in XAML bindings, backed by an auto-generated strongly-typed resource class (`StringResources`) containing localized strings for channel configuration UI elements, parameter labels, validation messages, and user-facing text. The module supports the configuration and display of various channel types including Analog, CAN, Digital I/O, Squib, Stream, and UART channels.
|
||||
|
||||
---
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### TranslateExtension (Markup Extension)
|
||||
|
||||
**Class Definition:**
|
||||
```csharp
|
||||
[MarkupExtensionReturnType(typeof(string))]
|
||||
public class TranslateExtension : MarkupExtension
|
||||
```
|
||||
|
||||
**Constructor:**
|
||||
```csharp
|
||||
public TranslateExtension(string key)
|
||||
```
|
||||
- Creates an instance with the specified resource key to look up.
|
||||
|
||||
**Public Method:**
|
||||
```csharp
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
```
|
||||
- Returns the localized string for the key stored in `_key` by querying `StringResources.ResourceManager.GetString(_key)`.
|
||||
- Returns `NotFound` ("#stringnotfound#") if `_key` is null or empty.
|
||||
- Returns `NotFound + " " + _key` (e.g., "#stringnotfound# SomeKey") if the resource lookup returns null.
|
||||
|
||||
**Private Constants:**
|
||||
- `private const string NotFound = "#stringnotfound#"` — Fallback value for missing keys.
|
||||
|
||||
---
|
||||
|
||||
### StringResources (Auto-Generated Resource Class)
|
||||
|
||||
**Class Definition:**
|
||||
```csharp
|
||||
internal class StringResources
|
||||
```
|
||||
- Internal class; not accessible outside the `GroupChannelList.Resources` namespace.
|
||||
|
||||
**Static Properties:**
|
||||
|
||||
| Property | Description (from source comments) |
|
||||
|----------|-------------------------------------|
|
||||
| `ResourceManager` | Returns cached `ResourceManager` instance for this assembly. |
|
||||
| `Culture` | Gets/sets `CultureInfo` for resource lookups. |
|
||||
|
||||
**Resource String Properties (selected):**
|
||||
|
||||
| Property | Default Text |
|
||||
|----------|--------------|
|
||||
| `AnalogParameter_ACCouplingEnable` | "AC coupling enabled" |
|
||||
| `AnalogParameters_Capacity` | "Sensor max range" |
|
||||
| `AnalogParameters_CFC` | "Channel filter class" |
|
||||
| `AnalogParameters_InitialOffset` | "Initial offset" |
|
||||
| `AnalogParameters_MaximumUsage` | "Maximum Usage" |
|
||||
| `AnalogParameters_Polarity` | "Polarity" |
|
||||
| `AnalogParameters_Range` | "Channel full-scale" |
|
||||
| `AnalogParameters_Sensitivity` | "Sensitivity" |
|
||||
| `AnalogParameters_Units` | "Units" |
|
||||
| `AnalogParameters_UsageCount` | "Usage Count" |
|
||||
| `AnalogParameters_UserValue1/2/3` | "User Value 1/2/3" |
|
||||
| `AnalogParameters_ZeroMethod` | "Zero Method" |
|
||||
| `AnalogParameters_ZeroMethodEnd` | "End (sec)" |
|
||||
| `AnalogParameters_ZeroMethodStart` | "Start (sec)" |
|
||||
| `CanParameters_ArbBaseBitrate` | "Arb/Base Bitrate" |
|
||||
| `CanParameters_ArbBaseSJW` | "Arb/Base SJW" |
|
||||
| `CanParameters_DataBitrate` | "Data Bitrate" |
|
||||
| `CanParameters_DataSJW` | "Data SJW" |
|
||||
| `CanParameters_FileType` | "FileType" |
|
||||
| `CanParameters_IsFD` | "CAN is FD" |
|
||||
| `DigitalInParameters_ActiveValue` | "Active value" |
|
||||
| `DigitalInParameters_DefaultValue` | "Default value" |
|
||||
| `DigitalInParameters_InputMode` | "Input mode" |
|
||||
| `DigitalOutParameters_Delay` | "Delay (ms)" |
|
||||
| `DigitalOutParameters_Duration` | "Duration (ms)" |
|
||||
| `DigitalOutParameters_LimitDuration` | "Limit duration" |
|
||||
| `DigitalOutParameters_OutputMode` | "Output mode" |
|
||||
| `SquibParameters_Current` | "Current (A)" |
|
||||
| `SquibParameters_Delay` | "Delay (ms)" |
|
||||
| `SquibParameters_Duration` | "Duration (ms)" |
|
||||
| `SquibParameters_FireMode` | "Fire mode" |
|
||||
| `SquibParameters_LimitDuration` | "Limit duration" |
|
||||
| `StreamInParameters_UDPAddress` | "UDP Address" |
|
||||
| `StreamOutParameters_DataChannelId` | "Data channel id" |
|
||||
| `StreamOutParameters_IENA_Key` | "IENA key" |
|
||||
| `StreamOutParameters_IENA_SourcePort` | "Source port" |
|
||||
| `StreamOutParameters_IRIGTimeDataPacketIntervalMs` | "IRIG time data packet interval (ms)" |
|
||||
| `StreamOutParameters_StreamProfile` | "Stream profile" |
|
||||
| `StreamOutParameters_TimeChannelId` | "Time channel id" |
|
||||
| `StreamOutParameters_TMATSIntervalMs` | "TMATS interval (ms)" |
|
||||
| `StreamOutParameters_TMNS_MessageId` | "Message Id" |
|
||||
| `StreamOutParameters_TMNS_MinorPerMajor` | "Minor per major" |
|
||||
| `StreamOutParameters_TMNS_SubFrameId` | "Subframe Id" |
|
||||
| `StreamOutParameters_TMNS_TMATSPort` | "TMATS port" |
|
||||
| `StreamOutParameters_TmNSConfig` | "TmNS config" |
|
||||
| `StreamOutParameters_UDPAddress` | "UDP Address" |
|
||||
| `UartParameters_BaudRate` | "Baud rate" |
|
||||
| `UartParameters_DataBits` | "Data bits" |
|
||||
| `UartParameters_DataFormat` | "Data format" |
|
||||
| `UartParameters_FlowControl` | "Flow control" |
|
||||
| `UartParameters_Parity` | "Parity" |
|
||||
| `UartParameters_StopBits` | "Stop bits" |
|
||||
| `ChannelName` | "Channel name" |
|
||||
| `ChannelType` | "Type" |
|
||||
| `Channels` | " channel(s) in " |
|
||||
| `Clear` | "Clear" |
|
||||
| `Delete` | "Delete" |
|
||||
| `DisplayName` | "Display name" |
|
||||
| `DisplayOrder` | "Display order" |
|
||||
| `DragAndDropFilterWarning` | "Drag and drop operation completed. Note that the table is currently being filtered..." |
|
||||
| `DuplicateSensor` | "Sensor appears more than once" |
|
||||
| `EnterValue` | "Enter value" |
|
||||
| `GlobalRangeCAC` | "Global range (CAC)" |
|
||||
| `Group` | "Group" |
|
||||
| `GroupLower` | "group" |
|
||||
| `Hardware` | "Hardware" |
|
||||
| `IEPESupport` | "IEPE support" |
|
||||
| `IntervalOn` | "On" |
|
||||
| `InvalidAnalogAssignment` | "Sensor {0} can not be assigned to channel {1}" |
|
||||
| `InvalidDigitalInputAssignment` | "DigitalInput {0} can not be assigned to channel {1}" |
|
||||
| `InvalidDigitalOutputAssignment` | "DigitalOutput {0} can not be assigned to channel {1}" |
|
||||
| `InvalidExcitationAssignment` | "Sensor {0} does not support any of the excitation options provided by channel {1}" |
|
||||
| `InvalidLine` | "Invalid pasted group channel, line: {0}" |
|
||||
| `InvalidSensor` | "Invalid sensor, line: {0}" |
|
||||
| `InvalidSquibAssignment` | "Squib {0} can not be assigned to channel {1}" |
|
||||
| `ISOAndUserCode` | "ISO 13499 and user codes" |
|
||||
| `ISOChannelName` | "ISO channel name" |
|
||||
| `ISOCode` | "ISO (13499) code" |
|
||||
| `ISOOnly` | "ISO 13499 only" |
|
||||
| `ModifyGlobalRangeCAC` | "Modify global range CAC" |
|
||||
| `Not_Applicable` | "N/A" |
|
||||
| `Of` | " of " |
|
||||
| `Order` | "Order" |
|
||||
| `Parameters_Analog` | "Analog" |
|
||||
| `Parameters_CAN` | "CAN" |
|
||||
| `Parameters_DigitalIn` | "Digital in" |
|
||||
| `Parameters_DigitalOut` | "Digital out" |
|
||||
| `Parameters_Squib` | "Squib" |
|
||||
| `Parameters_StreamIn` | "Stream in" |
|
||||
| `Parameters_StreamOut` | "Stream out" |
|
||||
| `Parameters_Uart` | "UART" |
|
||||
| `PhysicalChannelsAssigned` | " physical channel(s) assigned" |
|
||||
| `RemoveSensor` | "Remove Sensor" |
|
||||
| `Sensor` | "Sensor (SN)" |
|
||||
| `DallasId` | "Dallas ID" |
|
||||
| `AssignedBySensorId` | "(Assigned by ID)" |
|
||||
| `btnApplyGlobalRangeCAC` | "Apply" |
|
||||
| `ChannelDelete_Tooltip` | "To delete a channel, please contact an Administrator" |
|
||||
| `Table_NA` | "---" |
|
||||
| `Test` | "test" |
|
||||
| `TestChannelsGroupName` | "Test channels" |
|
||||
| `UserChannelName` | "User channel name" |
|
||||
| `UserCode` | "User code" |
|
||||
| `UserCodeOnly` | "User codes only" |
|
||||
|
||||
---
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
1. **TranslateExtension key requirement**: The `_key` field is set via constructor and is `readonly`. It cannot be changed after instantiation.
|
||||
|
||||
2. **Missing resource handling**: `ProvideValue` will never return null. It returns either:
|
||||
- The localized string from resources
|
||||
- `#stringnotfound#` (if key is null/empty)
|
||||
- `#stringnotfound# {key}` (if key exists but no matching resource)
|
||||
|
||||
3. **StringResources visibility**: The `StringResources` class is `internal` and cannot be accessed outside the `GroupChannelList.Resources` namespace.
|
||||
|
||||
4. **ResourceManager singleton pattern**: The `ResourceManager` property uses lazy initialization with a null-check pattern; once initialized, the same instance is returned on subsequent calls.
|
||||
|
||||
5. **Auto-generated code constraint**: `StringResources.Designer.cs` is auto-generated by `System.Resources.Tools.StronglyTypedResourceBuilder` version 17.0.0.0. Manual changes will be overwritten on regeneration.
|
||||
|
||||
---
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This module depends on:
|
||||
- `System` (core .NET framework)
|
||||
- `System.Windows.Markup` (for `MarkupExtension` and `MarkupExtensionReturnTypeAttribute`) — WPF-specific
|
||||
- `System.Resources` (for `ResourceManager`)
|
||||
- `System.Globalization` (for `CultureInfo`)
|
||||
- `System.CodeDom.Compiler`, `System.Diagnostics`, `System.Runtime.CompilerServices`, `System.ComponentModel` (for generated attributes)
|
||||
|
||||
### What depends on this module:
|
||||
- **Inferred**: XAML files within the `GroupChannelList` module that use the `{local:Translate KeyName}` markup extension syntax for localized UI strings.
|
||||
- **Inferred**: Code-behind files that reference `StringResources` properties directly (though the class is `internal`, limiting this to within the assembly).
|
||||
|
||||
---
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **Missing key indicator**: When a resource key is not found, the returned string includes the key name appended (e.g., `#stringnotfound# MyMissingKey`). This is useful for debugging but may appear in production UI if resources are missing.
|
||||
|
||||
2. **Null/empty key handling**: Passing `null` or empty string to `TranslateExtension` constructor returns only `#stringnotfound#` without a key suffix, making it impossible to distinguish which empty/null key caused the issue.
|
||||
|
||||
3. **Auto-generated file warning**: `StringResources.Designer.cs` is regenerated from a `.resx` file. Developers should not edit this file directly; instead, modify the underlying `.resx` file and regenerate.
|
||||
|
||||
4. **Culture not explicitly set**: The `TranslateExtension.ProvideValue` method does not explicitly pass a `CultureInfo` to `GetString()`. It relies on `StringResources.ResourceManager.GetString(key)` which uses the current UI culture. If `StringResources.Culture` is set, it must be done separately; the markup extension does not interact with it.
|
||||
|
||||
5. **Internal visibility limitation**: `StringResources` is `internal`, meaning direct programmatic access to resource strings is restricted to within the `GroupChannelList.Resources` namespace/assembly. External consumers must use `TranslateExtension` in XAML or use reflection.
|
||||
100
docs/ai/DataPRO/Modules/Groups/GroupChannelList/View.md
Normal file
100
docs/ai/DataPRO/Modules/Groups/GroupChannelList/View.md
Normal file
@@ -0,0 +1,100 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/Modules/Groups/GroupChannelList/View/GroupChannelListView.xaml.cs
|
||||
generated_at: "2026-04-17T15:58:43.555476+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "d3939bb26e2af959"
|
||||
---
|
||||
|
||||
# GroupChannelListView Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
`GroupChannelListView` is a WPF UserControl (code-behind) that provides the view layer for displaying and managing a list of group channels in a tabular format. It handles user interactions including drag-and-drop sensor/hardware assignment, channel reordering, column visibility management based on view modes, and navigation events. This view implements `IGroupChannelListView` and serves as the UI component within the Groups module for configuring channel assignments in test setups and group configurations.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Properties
|
||||
|
||||
| Signature | Description |
|
||||
|-----------|-------------|
|
||||
| `bool ReadOnlyChannelsMode { get; }` | Returns whether user input controls should be read-only. Delegates to `IGroupChannelListViewModel.ReadOnlyChannelsMode` if DataContext is valid; otherwise returns `false`. |
|
||||
|
||||
### Methods
|
||||
|
||||
| Signature | Description |
|
||||
|-----------|-------------|
|
||||
| `void HandleColumns(IsoViewMode viewMode)` | Dynamically configures column visibility based on the specified `IsoViewMode`. Manages Group, ISO Code, User Code, Dallas ID, and Test Setup Order columns. Reads global setting "ShowGroups" to determine group column visibility. |
|
||||
|
||||
### Constructor
|
||||
|
||||
| Signature | Description |
|
||||
|-----------|-------------|
|
||||
| `GroupChannelListView()` | Initializes the component and subscribes to `ListViewStatusEvent` via `IEventAggregator` to handle scroll-to-bottom requests. |
|
||||
|
||||
### Event Handlers (Private, wired to XAML)
|
||||
|
||||
| Method | Trigger | Behavior |
|
||||
|--------|---------|----------|
|
||||
| `Clear_Click(object sender, RoutedEventArgs e)` | Clear button click | Calls `viewModel.Clear(channel)` and `viewModel.NotifyChannelsChanged()` for the affected `IGroupChannel`. |
|
||||
| `Delete_Click(object sender, RoutedEventArgs e)` | Delete button click | Publishes `GroupChannelDeleteRequestEvent` with `GroupChannelDeleteRequestEventArgs`. Special handling for blank channels with order values (bug fix 14546). |
|
||||
| `MoveTop_Click`, `MoveUp_Click`, `MoveDown_Click`, `MoveBottom_Click` | Move button clicks | Calls corresponding `vm.MoveTop()`, `vm.MoveUp()`, `vm.MoveDown()`, `vm.MoveBottom()` methods. Supports multi-selection via `GetSelectedChannelsOrdered()`. |
|
||||
| `ChannelList_Drop(object sender, DragEventArgs e)` | Drop operation | Handles `DragAndDropPayload.FORMAT` for sensor assignment and `DTS.Common.Classes.Hardware.DragAndDropPayload.FORMAT` for hardware assignment via `vm.DoSensorAssignment()` and `vm.DoHardwareAssignment()`. |
|
||||
| `TextBox_Drop(object sender, DragEventArgs e)` | Drop on text box | Same drop handling as `ChannelList_Drop`, but extracts `IGroupChannel` from `Control.DataContext` or `TextBlock.DataContext`. |
|
||||
| `ChannelCodeBuilder_OnChannelCodeSelected(object sender, string code, string name, ChannelEnumsAndConstants.ChannelCodeType codeType)` | Channel code selection | Sets `IsoCode`/`IsoChannelName` or `UserCode`/`UserChannelName` based on `codeType`. Calls `viewModel.MarkModified(channel)`. |
|
||||
| `ChannelNameBuilder_OnChannelCodeSelected(...)` | Channel name selection | Similar to above but sets name first, then code. |
|
||||
| `ISOCode_LostFocus(object sender, RoutedEventArgs e)` | ISO Code field loses focus | If `UseISOCodeFilterMapping` is true, retrieves software filters and calls `channel.GetFilterClassFromISOCode()` to set `FilterClass`. |
|
||||
| `Hyperlink_Click(object sender, RoutedEventArgs e)` | Hyperlink click | Publishes `PageNavigationRequestEvent` with destination `Sensor` for navigation. |
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
- **DataContext Contract**: Most operations assume `DataContext` is either `IGroupChannelListViewModel` or `GroupChannelListViewModel`. Operations silently return if this contract is violated.
|
||||
- **Column Management**: `ChannelListListView.View` must be of type `DTS.Common.Controls.AutoSizedGridView` for column manipulation methods to function.
|
||||
- **Drag-Drop Payload Formats**: The view recognizes specific format strings:
|
||||
- `DragAndDropPayload.FORMAT` and `DragAndDropPayload.ALT_FORMAT` for sensor payloads
|
||||
- `DTS.Common.Classes.Hardware.DragAndDropPayload.FORMAT` for hardware payloads
|
||||
- **Selection Ordering**: `GetSelectedChannelsOrdered()` returns channels sorted by their index in `ChannelListListView.Items`, preserving visual order.
|
||||
- **Order Column Exclusivity**: Either `TestSetupOrderColumn` or `GroupOrderColumn` is displayed at index 0, never both simultaneously.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### Imports (This module depends on)
|
||||
|
||||
| Namespace | Purpose |
|
||||
|-----------|---------|
|
||||
| `DTS.Common.Classes.Groups` | `GroupChannel` entity |
|
||||
| `DTS.Common.Classes.Sensors.SensorsList` | Sensor-related types |
|
||||
| `DTS.Common.Controls` | `AutoSizedGridView`, `GridViewColumnHeaderSearchable` |
|
||||
| `DTS.Common.Enums` | `IsoViewMode` enum |
|
||||
| `DTS.Common.Enums.Channels` | `ChannelEnumsAndConstants` |
|
||||
| `DTS.Common.Events` | `PageNavigationRequestEvent`, `PageNavigationRequest` |
|
||||
| `DTS.Common.Events.Groups.GroupChannelList` | `ListViewStatusEvent`, `ListViewStatusArg`, `GroupChannelDeleteRequestEvent`, `GroupChannelDeleteRequestEventArgs` |
|
||||
| `DTS.Common.Interface.Channels` | `IHardwareChannel` |
|
||||
| `DTS.Common.Interface.DataRecorders` | Data recorder interfaces |
|
||||
| `DTS.Common.Interface.Groups.GroupChannelList` | `IGroupChannelListView`, `IGroupChannelListViewModel`, `IGroupChannel` |
|
||||
| `DTS.Common.Settings` | `SettingsDB.GetGlobalValueBool()` |
|
||||
| `DTS.Common.Utils` | `MouseUtilities` for drag-drop coordinate handling |
|
||||
| `Prism.Ioc` | `ContainerLocator` for service resolution |
|
||||
| `Prism.Events` | `IEventAggregator` for pub/sub messaging |
|
||||
| `DTS.SensorDB` | `SoftwareFilter.GetSoftwareFilters()` (referenced in `ISOCode_LostFocus`) |
|
||||
|
||||
### Known Dependents
|
||||
|
||||
Not determinable from this source file alone.
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **Drag-Drop Mouse Position**: The code explicitly uses `MouseUtilities.GetMousePosition(target)` instead of standard WPF mechanisms because "during a drag-drop operation, the WPF mechanisms for getting the coordinates behave strangely."
|
||||
|
||||
2. **Blank Channel Deletion (Bug 14546)**: Blank channels may still have `TestSetupOrder` or `GroupChannelOrder` assigned. The delete logic allows deletion of blank channels only if their order value is greater than 0, depending on `UseTestSetupOrder` mode.
|
||||
|
||||
3. **Modifier Key Format Mutation**: During drag operations, the code mutates format strings by prepending `"ALT_"` or `"CTRL_"` based on `DragDropKeyStates`. This creates format strings like `"ALT_FORMAT"` that must match expected payload constants.
|
||||
|
||||
4. **Inconsistent Drag-Over Behavior**: `ChannelList_DragOver` allows `DragAndDropPayload.ALT_FORMAT` but `TextBox_DragOver` handles it differently—some formats that are allowed in list-level drag-over are rejected in text-box drag-over.
|
||||
|
||||
5. **Hardcoded Column Dependencies**: `AddDallasIdColumn()` relies on `HardwareColumn` existing to determine insertion index. If `HardwareColumn` is not in the view, the insertion logic may fail or insert at an unexpected position.
|
||||
|
||||
6. **Empty Event Handler**: `ChannelListListView_SelectionChanged` is wired but contains no implementation.
|
||||
|
||||
7. **Global Setting Dependency**: `HandleColumns` reads `"ShowGroups"` global setting via `SettingsDB.GetGlobalValueBool()` with default `true`. This creates implicit runtime configuration dependency.
|
||||
111
docs/ai/DataPRO/Modules/Groups/GroupChannelList/ViewModel.md
Normal file
111
docs/ai/DataPRO/Modules/Groups/GroupChannelList/ViewModel.md
Normal file
@@ -0,0 +1,111 @@
|
||||
---
|
||||
source_files:
|
||||
- DataPRO/Modules/Groups/GroupChannelList/ViewModel/GroupChannelListViewModel.cs
|
||||
generated_at: "2026-04-17T16:01:14.282913+00:00"
|
||||
model: "zai-org/GLM-5-FP8"
|
||||
schema_version: 1
|
||||
sha256: "593e1e1e445f103d"
|
||||
---
|
||||
|
||||
# GroupChannelListViewModel Documentation
|
||||
|
||||
## 1. Purpose
|
||||
|
||||
The `GroupChannelListViewModel` class serves as the presentation logic layer for managing channel configurations within Groups and Test Setups in a data acquisition system. It orchestrates the assignment of sensors and hardware channels, handles text parsing for bulk channel creation, manages filtering and sorting of channel lists, and coordinates UI interactions through Prism's event aggregation system. The class supports both Group-based channel management and Test Setup ordering modes, providing bidirectional synchronization between channel properties and underlying data models.
|
||||
|
||||
## 2. Public Interface
|
||||
|
||||
### Properties
|
||||
|
||||
| Signature | Description |
|
||||
|-----------|-------------|
|
||||
| `IGroupChannelListView View { get; set; }` | The associated view instance. |
|
||||
| `IGroupChannelSettingsListView SettingsView { get; set; }` | The settings view instance. |
|
||||
| `InteractionRequest<Notification> NotificationRequest { get; }` | Interaction request for displaying notifications. |
|
||||
| `InteractionRequest<Confirmation> ConfirmationRequest { get; }` | Interaction request for displaying confirmations. |
|
||||
| `bool SettingsViewLoaded { get; set; }` | Indicates whether the SettingsView has loaded. |
|
||||
| `bool SettingChannelsLoaded { get; set; }` | Indicates whether SettingChannel UI elements were created. |
|
||||
| `event PropertyChangedEventHandler PropertyChanged` | Property change notification event. |
|
||||
|
||||
### Methods
|
||||
|
||||
| Signature | Description |
|
||||
|-----------|-------------|
|
||||
| `void OnPropertyChanged(string propertyName)` | Raises `PropertyChanged` event; publishes `GroupChannelsChangedEvent` when `ChannelCount` changes. |
|
||||
| `void UpdateRangeLowG(IGroupChannel channelChanged)` | Updates all Low G channels on the same DAS to match the range of the changed channel. |
|
||||
| `void UpdateRangeARS(IGroupChannel channelChanged)` | Updates all ARS channels on the same DAS to match the range of the changed channel. |
|
||||
| `void UpdateACCouplingEnabled(IGroupChannel channelChanged)` | Propagates AC coupling enabled state to other channels on the same DAS. |
|
||||
| `IGroup CreateGroupIfNeeded(ITestSetup testSetup, string groupName)` | Creates a group if it doesn't exist; delegates to `GroupList.Model.Group.CreateGroupIfNeeded`. |
|
||||
| `void DoSensorAssignment(IGroupChannel groupChannel, IDragAndDropItem[] sensors)` | Assigns sensors to channels starting at the specified channel index. Refuses assignment to TSR AIR channels (non-StreamOut/non-Uart). |
|
||||
| `void DoHardwareAssignment(IGroupChannel groupChannel, IHardwareChannel[] hardwareChannels)` | Assigns hardware channels starting at the specified index. TSR AIR hardware has special restrictions. |
|
||||
| `void Unset()` | Clears all channels, dictionaries, and filters; resets view state. |
|
||||
| `void ClearAllFilters()` | Resets search term, bridge filter, and field filters; publishes `ListViewStatusEvent`. |
|
||||
| `void OnSetActive()` | Refreshes channel state, column visibility, and UI bindings when the view becomes active. |
|
||||
| `bool CompareAndMarkChannelParameters(IGroupChannel ch)` | Compares channel parameters against sensor database values; marks differences for UI decoration. |
|
||||
| `IDictionary<IGroup, IGroupChannel[]> PopulateChannels(object page, IDictionary<int, ISensorData> sensorLookup, IDictionary<int, IDASHardware> hardwareLookup, IChannelSetting[] channelDefaults, bool allowChannelDeletionByNonAdminUser = true, bool userIsAdmin = true, bool allowSensorPushAndPull = false, bool keepExistingChannels = false, bool allowChannelDeletionFromFixedGroup = false)` | Populates channel lists from sensor and hardware lookups; handles TSR AIR embedded sensors and fixed group constraints. |
|
||||
| `void Cleanup()` | Empty cleanup method. |
|
||||
| `Task CleanupAsync()` | Returns `Task.CompletedTask`. |
|
||||
| `void Initialize()`, `void Initialize(object parameter)`, `void Initialize(object parameter, object model)` | Empty initialization methods. |
|
||||
| `Task InitializeAsync()`, `Task InitializeAsync(object parameter)` | Return `Task.CompletedTask`. |
|
||||
| `void Activated()` | Empty activation method. |
|
||||
| `void ReportErrors(string[] errors)` | Publishes `PageErrorEvent` with provided errors. |
|
||||
| `void GroupNameChanged(IGroupChannel channel)` | Handles group name changes in Test Setup mode; removes channel from old group, creates new group if needed. |
|
||||
| `void MarkModified(IGroupChannel channel, bool bNotifyChanged = true)` | Marks a channel as modified; adds a new blank channel if modifying the last one. |
|
||||
| `void NotifyChannelsChanged()` | Publishes `PageModifiedEvent` and `GroupUpdatedEvent`; raises property change for counts. |
|
||||
| `void Clear(IGroupChannel channel)` | Clears the specified channel's data. |
|
||||
| `void Remove(IGroupChannel channel, bool notifyChanged = true)` | Removes a channel from the list; handles Test Setup group cleanup. |
|
||||
|
||||
## 3. Invariants
|
||||
|
||||
1. **Blank Channel at End**: `AllChannels` and `Channels` collections always contain a blank `GroupChannel` at the end, used for adding new channels via `MarkModified`.
|
||||
|
||||
2. **TSR AIR Channel Restrictions**: Channels with `HardwareChannel.IsTSRAIR == true` (excluding StreamOut and Uart types) cannot have sensors or hardware reassigned via drag-and-drop.
|
||||
|
||||
3. **Channel Ordering**: Channels maintain either `TestSetupOrder` or `GroupChannelOrder` (1-indexed), determined by `UseTestSetupOrder` property.
|
||||
|
||||
4. **ISO Code Length**: ISO codes are truncated to 16 characters maximum in `ParseText`.
|
||||
|
||||
5. **Move Button State**: The first channel has `CanMoveUp = false`; the last non-blank channel has `CanMoveDown = false`.
|
||||
|
||||
6. **Filter Preservation**: Channels in `_dontFilterList` are excluded from filtering operations to maintain visibility during editing.
|
||||
|
||||
7. **Fixed Group Deletion**: When `AllowChannelDeletionFromFixedGroup = false`, channels with non-null `StaticGroupId` have `DeleteShouldBeEnabled = false`.
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
### This Module Depends On:
|
||||
- **Prism Framework**: `IEventAggregator`, `IRegionManager`, `Delegate` commands, `InteractionRequest`
|
||||
- **Unity Container**: `IUnityContainer` for service resolution
|
||||
- **DTS.Common.Classes.Groups**: `Group` model class
|
||||
- **DTS.Common.Enums**: `HardwareTypes`, `PossibleFilters`, `Fields`, sensor enums
|
||||
- **DTS.Common.Events**: `GroupChannelsChangedEvent`, `RaiseNotification`, `BusyIndicatorChangeNotification`, `TextPastedEvent`, `PageErrorEvent`, `PageModifiedEvent`, `GroupUpdatedEvent`, `AppStatusEvent`, `ListViewStatusEvent`
|
||||
- **DTS.Common.Interface.Channels**: `IHardwareChannel`, `IChannelCode`, `IChannelSetting`
|
||||
- **DTS.Common.Interface.Groups.GroupChannelList**: `IGroupChannelListView`, `IGroupChannelSettingsListView`, `IGroupChannel`
|
||||
- **DTS.Common.Interface.Sensors**: `ISensorData`, `IDragAndDropItem`
|
||||
- **DTS.Common.Storage**: `DbOperations` for channel setting defaults
|
||||
- **DTS.Common.Constants**: `TDAS_TOM_DIGITAL_OUT_DURATION_MAX`
|
||||
- **System.ComponentModel.Composition**: `[PartCreationPolicy(CreationPolicy.Shared)]` for MEF
|
||||
|
||||
### Events Consumed:
|
||||
- `RaiseNotification` → `OnRaiseNotification`
|
||||
- `BusyIndicatorChangeNotification` → `OnBusyIndicatorNotification`
|
||||
- `TextPastedEvent` → `OnTextPasted`
|
||||
|
||||
### Events Published:
|
||||
- `GroupChannelsChangedEvent`, `PageErrorEvent`, `PageModifiedEvent`, `GroupUpdatedEvent`, `AppStatusEvent`, `ListViewStatusEvent`
|
||||
|
||||
## 5. Gotchas
|
||||
|
||||
1. **TSR AIR Embedded Sensors**: The `PopulateChannels` method contains special logic to handle embedded sensors in TSR-AIR units, only adding them if the unit isn't already represented in the group. This logic is spread across multiple checks and can be difficult to follow.
|
||||
|
||||
2. **Sensor Serial Number Parsing**: `GetSensorSerialNumber` handles sensors with names in format `"Name (SerialNumber)"` vs. just `"SerialNumber"`. The dictionary lookup depends on this parsing being consistent.
|
||||
|
||||
3. **Blank Channel Management**: The blank channel at the end of lists is both a UI affordance and a state management mechanism. Removing or modifying it triggers creation of a new blank channel, which can cause unexpected list changes.
|
||||
|
||||
4. **Test Setup vs. Group Mode**: Many methods check `UseTestSetupOrder` to determine behavior. The same ViewModel serves both contexts, and some operations (like `GroupNameChanged`) are no-ops in Group mode.
|
||||
|
||||
5. **Filter State Persistence**: `_dontFilterList` is cleared on user-initiated filter operations but preserved during programmatic filtering. This can lead to unexpected channel visibility if not managed carefully.
|
||||
|
||||
6. **Digital Out Duration Max**: TDAS TOM hardware has a hardcoded max value (`TDAS_TOM_DIGITAL_OUT_DURATION_MAX`) applied in `ResetSettingChannels`, separate from other channel validation.
|
||||
|
||||
7. **Sensor Push/Pull**: The `AllowSensorPushAndPull` flag affects whether channel parameters are compared against sensor database values and whether `BorderShouldShowOutOfDate` is set. This feature appears to be for highlighting parameter drift from sensor defaults.
|
||||
Reference in New Issue
Block a user