Files
DP44/enriched-qwen3-coder-next/DataPRO/Modules/ISO/ExtraProperties/ViewModel.md
2026-04-17 14:55:32 -04:00

9.0 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/Modules/ISO/ExtraProperties/ViewModel/ExtraPropertiesListViewModel.cs
2026-04-16T04:38:41.881863+00:00 Qwen/Qwen3-Coder-Next-FP8 1 d7dc80e73ad032ff

ViewModel

ExtraPropertiesListViewModel Documentation


1. Purpose

ExtraPropertiesListViewModel is a Prism-based ViewModel responsible for managing a list of key-value extra properties associated with a data page in the ISO module of the DataPRO application. It provides UI-agnostic data binding, sorting, filtering, clipboard operations (copy/paste), validation, and event-driven integration with the broader application via IEventAggregator. It serves as the intermediary between the IExtraPropertiesListView UI and the underlying ExtraPropertyModel data entities, enabling users to edit, sort, filter, and validate property lists (e.g., metadata, tags, or custom attributes) in a tabular UI.


2. Public Interface

All members are defined in ExtraPropertiesListViewModel, which implements IExtraPropertiesListViewModel (inferred from interface usage). Only explicitly declared public or interface-implementing members are documented.

Properties

Property Type Description
View IExtraPropertiesListView Reference to the associated view; set externally.
NotificationRequest InteractionRequest<Notification> Prism MVVM Toolkit interaction request for showing non-blocking notifications.
ConfirmationRequest InteractionRequest<Confirmation> Prism MVVM Toolkit interaction request for showing confirmation dialogs.
IsBusy bool Gets/sets busy state; raises PropertyChanged for "IsBusy".
IsMenuIncluded bool Gets/sets whether a context menu is included in the view; raises PropertyChanged for "IsMenuIncluded".
IsNavigationIncluded bool Gets/sets whether navigation controls are included; raises PropertyChanged for "IsNavigationIncluded".
IsReadOnly bool Gets/sets read-only mode (prevents editing); raises PropertyChanged for "IsReadOnly".
AllExtraProperties List<IExtraProperty> Full list of all extra properties (including empty trailing row).
ExtraProperties ObservableCollection<IExtraProperty> Filtered/sorted view of AllExtraProperties, bound to UI.
SelectedProperties IExtraProperty[] Throws NotImplementedException — not implemented.
Page IDataPROPage The page this ViewModel is associated with (set via SetPage).
Parent object Parent object (set via SetParent).
IsDirty bool Declared but never set; always false.

Events

Event Type Description
PropertyChanged PropertyChangedEventHandler Standard INotifyPropertyChanged event; raised via OnPropertyChanged.

Methods

Method Signature Description
OnPropertyChanged void OnPropertyChanged(string propertyName) Raises PropertyChanged; if propertyName == "ExtraProperties", publishes ExtraPropertiesChangedEvent.
SetPage void SetPage(IDataPROPage page) Sets Page.
SetParent void SetParent(object parent) Sets Parent.
Cleanup void Cleanup() No-op.
CleanupAsync Task CleanupAsync() Returns Task.CompletedTask.
Initialize / InitializeAsync Multiple overloads (e.g., void Initialize(), Task InitializeAsync(object parameter)) All are no-ops.
Activated void Activated() No-op.
Filter void Filter(object tag, string term) Sets search term for "Key" or "Value" (via tag string) and triggers Filter(). Bug: "Value" case incorrectly sets _searchTermForField[Fields.Key].
Sort void Sort(object columnTag, bool columnClick) Sets sort field ("Key" or "Value") and triggers Sort(...) + Filter().
Validate(ref List<string> errors) bool Validate(ref List<string> errors) Calls internal Validate(ref errors, ref warnings), returns true if no new errors added.
SetExtraProperties void SetExtraProperties(IList<IExtraProperty> properties) Replaces AllExtraProperties with copies of input properties, appends a new empty ExtraPropertyModel, resets sort/filter, and re-applies.
CopySelected void CopySelected() Copies selected items (_selectedItems) into AllExtraProperties (just before the trailing empty row), sorts, filters, and publishes PageModifiedEvent.
DeleteSelected void DeleteSelected() Removes selected items from both ExtraProperties and AllExtraProperties; ensures trailing empty row is preserved; publishes PageModifiedEvent.

Note

: SelectedProperties is declared but throws NotImplementedException. Its usage is likely incomplete or deprecated.


3. Invariants

  • Trailing Empty Row: AllExtraProperties always ends with a single empty ExtraPropertyModel instance (key/value both empty/whitespace). This is enforced in:
    • SetExtraProperties (adds one after copying input),
    • MarkModified (adds one if last item modified),
    • DeleteSelected (re-adds one if deleted).
  • Filtering Logic: Empty rows (both key and value whitespace) are always included in ExtraProperties regardless of search term.
  • Sorting Behavior: Empty rows are always sorted to the bottom of AllExtraProperties (via PropertyComparer.Compare).
  • Validation Rules:
    • Duplicate non-empty keys → error.
    • Non-empty keys with empty/whitespace values → warning.
  • Event Subscription Hack: _bAddListeners static flag ensures only the second instantiation of this ViewModel subscribes to TextPastedEvent. First instantiation (likely during app startup) skips subscription.

4. Dependencies

Imports / Dependencies Used

  • Prism Framework:
    • Prism.Events.IEventAggregator, Prism.Regions.IRegionManager
    • Prism.Interactivity.InteractionRequest (Notification, Confirmation)
  • Unity DI Container: IUnityContainer
  • DataPRO Common Libraries:
    • DTS.Common.Events.* (e.g., TextPastedEvent, PageModifiedEvent, PageSelectionChanged)
    • DTS.Common.Interface.* (IDataPROPage, IExtraProperty, IExtraPropertiesListView, IExtraPropertiesListViewModel)
    • DTS.Common.Utilities.NaturalStringComparer (used in PropertyComparer)
  • Model Layer:
    • ExtraProperties.Model.ExtraPropertyModel (concrete implementation of IExtraProperty)
  • Resources:
    • ExtraProperties.Resources.StringResources (for error/warning messages)

Consumers (Inferred)

  • ExtraPropertiesListViewModel is instantiated via Unity DI (due to [PartCreationPolicy(CreationPolicy.Shared)] and constructor injection).
  • Likely consumed by IExtraPropertiesListView (WPF view) bound to this ViewModel.
  • Subscribes to events published by other modules (e.g., TextPastedEvent from clipboard operations).
  • Publishes PageModifiedEvent, ExtraPropertiesChangedEvent, and PageSelectionChanged.

5. Gotchas

  • SelectedProperties is unimplemented: Throws NotImplementedException. Any code expecting this property will crash.
  • Filter bug: When filtering by "Value", it incorrectly assigns the term to _searchTermForField[Fields.Key] instead of Fields.Value.
  • _bAddListeners hack: Static boolean _bAddListeners controls TextPastedEvent subscription. First instantiation does not subscribe; only the second (and subsequent) do. This is fragile and may break if instantiation order changes.
  • IsDirty never set: Property is declared but never assigned; always false.
  • Sort/Filter order: Sort is called before Filter in Filter(object, string) and Sort(object, bool), but Filter() is called after Sort(...) in Paste, CopySelected, and DeleteSelected. This is consistent but non-obvious.
  • Paste behavior: Paste modifies ExtraProperties in-place (by index), but AllExtraProperties is not updated until Sort/Filter are called. This may cause inconsistency if accessed mid-operation.
  • Case sensitivity: Sorting and filtering use ToUpper() + NaturalStringComparer, which may not match user expectations for case-insensitive comparisons (e.g., "a" and "A" sort as equal, but "ä" vs "a" may behave unexpectedly).
  • No null checks in PropertyComparer: While left == right is handled, a/b could be null after assignment (e.g., if left/right are non-null but one becomes null after SortAscending swap logic). null checks exist but may not cover all paths.
  • MarkModified side effect: Appends a new empty row only if the modified item is the last in ExtraProperties, but uses ExtraProperties.Last() — which is the filtered list — not AllExtraProperties. This may cause inconsistent behavior if filtering is active.

Documentation generated from ExtraPropertiesListViewModel.cs (DataPRO/Modules/ISO/ExtraProperties/ViewModel/ExtraPropertiesListViewModel.cs).