Files
DP44/enriched-qwen3-coder-next/DataPRO/Modules/RegionOfInterest/RegionOfInterestChannels/View.md
2026-04-17 14:55:32 -04:00

9.8 KiB
Raw Blame History

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/Modules/RegionOfInterest/RegionOfInterestChannels/View/StateListIndexConverter.cs
DataPRO/Modules/RegionOfInterest/RegionOfInterestChannels/View/RegionOfInterestChannelsView.xaml.cs
DataPRO/Modules/RegionOfInterest/RegionOfInterestChannels/View/RegionOfInterestChannelsDataTemplateSelector.cs
DataPRO/Modules/RegionOfInterest/RegionOfInterestChannels/View/GridViewColumns.cs
2026-04-16T04:34:31.801575+00:00 Qwen/Qwen3-Coder-Next-FP8 1 b5797f8ba3342db7

View

Documentation: RegionOfInterestChannels View Layer


1. Purpose

This module provides WPF UI infrastructure for rendering and interacting with a GridView-based view of region-of-interest (ROI) channel data. It enables dynamic column generation from a data source, per-column type-aware cell templating (e.g., TextBlock vs. CheckBox), column header interactivity (sorting, filtering, multi-select), and automatic column width adjustment for content-fit. It serves as the view layer in an MVVM pattern, implementing IRegionOfInterestChannelsView and delegating user actions to an associated IRegionOfInterestChannelsViewModel.


2. Public Interface

StateListIndexConverter

Namespace: RegionOfInterestChannels
Implements: IMultiValueConverter

  • Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    Converts a 2-element multi-value binding: expects [0] = IEnumerable<State>, [1] = int index. Returns the State at the given index in the collection, or null if inputs are invalid or index is out of bounds.
    Note: Does not support ConvertBack.

RegionOfInterestChannelsView

Namespace: RegionOfInterestChannels
Implements: IRegionOfInterestChannelsView (partial class)

  • RegionOfInterestChannelsView()
    Constructor; calls InitializeComponent().

  • GridViewColumnHeader_OnClick(object sender, RoutedEventArgs e)
    Handles column header click events. Extracts the Tag from the clicked header (supporting GridViewColumnHeaderSearchable or GridViewColumnHeaderSelectable types), then invokes vm.Sort(columnTag, true) on the DataContext if it implements IRegionOfInterestChannelsViewModel.

  • TextBlock_Loaded(object sender, RoutedEventArgs e)
    Adjusts column width dynamically when a TextBlock in a cell is loaded and its content width exceeds the columns current width (only if Width is double.NaN). Finds the column index via visual tree traversal and temporarily sets Width = ActualWidth, then resets to NaN to trigger remeasurement.

RegionOfInterestChannelsDataTemplateSelector

Namespace: RegionOfInterestChannels
Inherits: DataTemplateSelector

  • TextBlockDataTemplate / CheckBoxDataTemplate
    Public properties for the two templates to select between.

  • SelectTemplate(object item, DependencyObject container)
    Selects a DataTemplate based on the cells underlying data type:

    • If item is a ChannelEnabler, inspects the columns header (as property name) to determine the property type on item.
      • If type is string → returns TextBlockDataTemplate; sets ContentPresenter.Tag to the property value.
      • If type is boolean (or other) → returns CheckBoxDataTemplate; sets ContentPresenter.Tag to the relative index of the column among boolean columns (i - checkStartColumn).
    • If item is not a ChannelEnabler, defaults to TextBlockDataTemplate.
      Note: Uses reflection (GetProperty, GetValue, GetType) on the item and presenter.Columns[i].Header. Assumes header text matches property names (with spaces removed).

GridViewColumns (Static Class)

Namespace: RegionOfInterestChannels
Purpose: Attached property provider for configuring GridView columns dynamically from an ICollectionView source.

Attached Properties:
  • ColumnsSource (object)
    Source collection (typically ICollectionView) whose items define columns. Changing this clears and recreates columns.

  • CellDataTemplateSelector (DataTemplateSelector)
    Optional selector used to choose per-cell templates.

  • CellDataTemplate (DataTemplate)
    Fallback template for cells if CellDataTemplateSelector is null.

  • HeaderTextMember (string)
    Property name on column source items whose value is used for column header text.

  • DisplayMember (string)
    Property name on column source items whose value is used as the binding path for cell content (currently commented out in CreateColumn).

Key Methods (Internal/Static):
  • CreateColumn(GridView gridView, object columnSource)
    Constructs a GridViewColumn from a columnSource item:

    • Reads HeaderTextMember and DisplayMember from gridView.
    • Determines column header type based on the column source items MemberType property (retrieved via GetPropertyValue(columnSource, "MemberType")):
      • typeof(bool)GridViewColumnHeaderSelectable with SelectAll event handler.
      • typeof(string)GridViewColumnHeaderSearchable with Search and ClickHandler events.
      • Otherwise → plain string header.
    • Assigns CellTemplateSelector, CellTemplate, and (commented-out) DisplayMemberBinding.
  • GetPropertyValue(object obj, string propertyName)
    Helper: uses reflection to get propertyName from obj.

  • GetArrayIndex(string fromString)
    Parses an integer from a string like "SomeProperty[3]", returning -1 on failure.

Event Handlers (Internal):
  • ColumnsSource_CollectionChanged(...)
    Syncs gridView.Columns with changes (Add, Remove, Replace, Move, Reset) in the ColumnsSource collection.

  • GridViewColumnHeaderSearchable_OnSearch(...)
    Invokes vm.Filter(columnTag, searchTerm).

  • GridViewColumnHeader_OnClick(...)
    Invokes vm.Sort(columnTag, true) (same behavior as RegionOfInterestChannelsView.GridViewColumnHeader_OnClick).

  • GridViewColumnHeaderSelectable_OnSelectAll(...)
    Parses column index from columnTag (e.g., "Enabled[2]"), then invokes vm.SelectAll(columnIndex, isSelected).


3. Invariants

  • Column Source Contract:
    Items in the ColumnsSource collection must have:

    • A property named "MemberType" (e.g., typeof(string) or typeof(bool)), used to determine header type.
    • Properties named by HeaderTextMember and DisplayMember (if set), or default to null.
  • Header Tag Format:
    For GridViewColumnHeaderSelectable, the Tag must be a string containing an array index in brackets (e.g., "Enabled[0]") to be parsed by GetArrayIndex.

  • StateListIndexConverter Input Expectation:
    Exactly two values: an IEnumerable<State> and an int. Any deviation yields null.

  • ChannelEnabler Assumption:
    RegionOfInterestChannelsDataTemplateSelector.SelectTemplate assumes item is a ChannelEnabler when inspecting property types. Behavior for other types is not defined in source.

  • Column Width Adjustment Scope:
    TextBlock_Loaded only adjusts the first matching ContentPresenter in the row. If multiple TextBlocks exist per row, only the first is considered.


4. Dependencies

Dependencies of this module:

  • WPF Framework: System.Windows, System.Windows.Controls, System.Windows.Data, System.Windows.Media.
  • Common Libraries:
    • DTS.Common.Controls (for GridViewColumnHeaderSearchable, GridViewColumnHeaderSelectable)
    • DTS.Common.Interface.RegionOfInterest.RegionOfInterestChannels (for IRegionOfInterestChannelsView, IRegionOfInterestChannelsViewModel)
    • DTS.Common.Utils (for Utils.FindChild<T>)

Dependencies on this module:

  • IRegionOfInterestChannelsViewModel must be implemented by the DataContext for RegionOfInterestChannelsView to handle sorting, filtering, and selection.
  • State type is used by StateListIndexConverter (imported from elsewhere in the codebase).
  • ChannelEnabler type is used by RegionOfInterestChannelsDataTemplateSelector (imported from elsewhere).

5. Gotchas

  • ConvertBack is Unimplemented:
    StateListIndexConverter.ConvertBack throws NotImplementedException. It is strictly a one-way converter.

  • DisplayMemberBinding is Commented Out:
    In CreateColumn, the line setting column.DisplayMemberBinding is commented. Cell binding relies entirely on CellDataTemplateSelector or CellDataTemplate. This may cause confusion if DisplayMember is set but unused.

  • Header Property Name Matching:
    RegionOfInterestChannelsDataTemplateSelector.SelectTemplate uses presenter.Columns[i].Header.ToString().Replace(" ", "") to match property names. If headers contain non-alphanumeric characters beyond spaces, reflection will fail.

  • MemberType Property Requirement:
    Column source items must expose a "MemberType" property (via reflection). If missing or non-Type, columnPropertyType becomes null, causing checkStartColumn to be set and defaulting to CheckBoxDataTemplate.

  • Duplicate Event Handlers Risk:
    ColumnsSource_CollectionChanged adds handlers to ICollectionView.CollectionChanged but does not deduplicate if ColumnsSource is reassigned to the same collection instance. This could lead to multiple handler invocations per event.

  • TextBlock_Loaded Fragility:
    Relies on a specific visual tree structure (GridViewRowPresenterContentPresenterTextBlock). Changes to control templates may break the width adjustment logic.

  • No Null-Safety for e?.OriginalSource:
    In GridViewColumnHeaderSelectable_OnSelectAll, (bool)(e?.OriginalSource ?? false) may throw InvalidCastException if e.OriginalSource is not a bool or null.