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

9.7 KiB
Raw Blame History

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/Modules/Hardware/AddEditHardware/ViewModel/AddEditHardwareViewModel.cs
2026-04-16T04:36:54.084304+00:00 Qwen/Qwen3-Coder-Next-FP8 1 eb93c7718734fde3

ViewModel

Documentation: AddEditHardwareViewModel


1. Purpose

This module implements the AddEditHardwareViewModel class, which serves as the view model for the Add/Edit Hardware UI flow. It encapsulates the logic for displaying, editing, and saving hardware configuration data (e.g., DAS units, SLICE6 devices), including validation, state management, and integration with other system modules (e.g., SLICE6 tree view, event aggregation, region navigation). It supports two operational modes: adding new hardware and editing existing hardware, and enforces constraints such as disallowing StandIn hardware in contexts where it is not permitted (e.g., data recorders). It acts as the intermediary between the UI (IAddEditHardwareView) and the underlying domain model (IAddEditHardwareHardware, IISOHardware), coordinating persistence and inter-module communication via Prism events.


2. Public Interface

AddEditHardwareViewModel(IAddEditHardwareView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)

  • Behavior: Primary constructor. Initializes the view, sets up event subscriptions (RaiseNotification, BusyIndicatorChangeNotification), and assigns dependencies. Assigns this as the views DataContext.

AddEditHardwareViewModel()

  • Behavior: Parameterless constructor required for XAML binding (e.g., design-time or Unity resolution fallback). Does not initialize dependencies.

void SetSLICE6TreeView(ISLICE6TreeView treeView, IHardwareListViewModel treeViewModel)

  • Behavior: Injects references to the SLICE6 tree view and its view model. Required for SLICE6-specific operations (e.g., saving associations, reloading tree). May be called after construction.

void Activated()

  • Behavior: Called when the view is activated. Enforces that StandIn is disabled if AllowStandin is false and the hardware instance is non-null.

void SetHardware(IDASHardware hw, IISOHardware isoHW)

  • Behavior: Initializes or resets the Hardware property. If hw is null, creates a new Model.Hardware instance; otherwise, constructs a new Model.Hardware from the provided hw and isoHW.

IISOHardware GetISOHardware()

  • Behavior: Converts the internal Hardware to an IISOHardware. If Hardware.StandIn is true and SerialNumber is not a valid GUID, generates a new GUID, updates both Hardware.SerialNumber and isoHW.SerialNumber, sets FirstUseDate to null, IsFirstUseValid to true, and CalDate to DateTime.Today.

bool Validate(IISOHardware isoHW, ref List<string> errors, ref List<string> warnings, bool displayWindow, bool IsAdd)

  • Behavior: Performs validation on isoHW. Checks:
    • Serial number validity (ValidateSerialNumber)
    • Uniqueness of serial number only if IsAdd is true (via Model.Hardware.CheckUniqueSN)
    • IP address validity (ValidateIPAddress)
  • Appends error/warning messages to errors/warnings. Calls PublishPageError if displayWindow is true. Returns false if any validation fails.

void PublishPageError(bool displayWindow, List<string> errors, List<string> warnings)

  • Behavior: If displayWindow is true and either errors or warnings is non-empty, publishes a PageErrorEvent with combined messages.

void SaveSLICE6Associations()

  • Behavior: If Hardware.HardwareType is SLICE6DB, SLICE6DB3, or SLICE6DB_InDummy, calls SLICE6TreeViewModel.SaveSLICE6Associations(Hardware.SerialNumber).

void Save()

  • Behavior: Persists the current Hardware via Model.Hardware.Save(...), passing TestId, and model.IsAdd. Then:
    • Calls SaveSLICE6Associations()
    • Publishes a HardwareSavedEvent with (DASId, SerialNumber)
    • Calls SLICE6TreeViewModel.LoadTreeView(SerialNumber) if SLICE6TreeViewModel is non-null.

void NotifyModified()

  • Behavior: If NotificationsOn is true, publishes a PageModifiedEvent with status Modified.

void Cleanup(), Task CleanupAsync(), void Initialize(), void Initialize(object), void Initialize(object, object), Task InitializeAsync(), Task InitializeAsync(object), void Unset()

  • Behavior: No-op stubs. Present to satisfy interface contracts (e.g., IInitialize, ICleanup), but contain no logic.

void OnPropertyChanged(string propertyName)

  • Behavior: Raises the PropertyChanged event for the specified property.

event PropertyChangedEventHandler PropertyChanged

  • Behavior: Standard INotifyPropertyChanged implementation.

Properties:

  • bool AllowStandin { get; set; } = true
    Controls whether StandIn hardware is permitted. Defaults to true. Set externally (e.g., false for data recorders).

  • IAddEditHardwareView View { get; set; }
    Reference to the associated view.

  • IAddEditHardwareHardware Hardware { get; set; }
    The current hardware instance. Setting it triggers property change notifications for Hardware, SerialNumber, FirmwareVersion, IPAddress, and calls SLICE6TreeViewModel.LoadTreeView(...).

  • int? TestId { get; set; }
    Optional test context ID, used during save.

  • bool NotificationsOn { get; set; } = false
    Enables/disables PageModifiedEvent publishing.

  • bool IsBusy { get; set; }
    Bound to busy indicator UI. Set via OnBusyIndicatorNotification.

  • bool IsMenuIncluded { get; set; }, bool IsNavigationIncluded { get; set; }
    UI layout flags; trigger OnPropertyChanged on change.

  • ISLICE6TreeView SLICE6TreeView { get; private set; }, IHardwareListViewModel SLICE6TreeViewModel { get; private set; }
    References injected via SetSLICE6TreeView. May be null.

  • InteractionRequest<Notification> NotificationRequest { get; }, InteractionRequest<Confirmation> ConfirmationRequest { get; }
    Prism interaction requests used to show popups (e.g., notifications, confirmations).


3. Invariants

  • Hardware is never null; defaults to new Model.Hardware() if SetHardware(null, ...) is called.
  • Hardware.StandIn is forced to false during Activated() if AllowStandin is false and Hardware is non-null.
  • Hardware.SerialNumber may be overwritten (replaced with a new GUID) in GetISOHardware() if StandIn is true and the current SerialNumber is not a valid GUID.
  • Validate(...) only enforces serial number uniqueness (CheckUniqueSN) when IsAdd is true.
  • IsBusy is updated synchronously on the publisher thread via OnBusyIndicatorNotification(bool).
  • SLICE6TreeViewModel may be null; all calls to it are guarded with ?..

4. Dependencies

Imports / Dependencies:

  • Prism Framework: IEventAggregator, IRegionManager, Unity, Prism.Events, Prism.Interactivity, Prism.Regions.
  • Common Libraries:
    • DTS.Common.Events.* (e.g., RaiseNotification, PageModifiedEvent, PageErrorEvent, HardwareSavedEvent)
    • DTS.Common.Interface.Hardware.AddEditHardware (IAddEditHardwareView, IAddEditHardwareHardware)
    • DTS.Common.Interface.DataRecorders (IDASHardware, IISOHardware)
    • DTS.Common.Interface.DASFactory.Diagnostics (ISLICE6TreeView)
    • DTS.Common.Interface.DASFactory.Diagnostics.HardwareList (IHardwareListViewModel)
    • DTS.Common.Utilities.Logging (APILogger)
    • DTS.Common.Interactivity (InteractionRequest<...>)
    • DTS.Common.Enums.Hardware.HardwareTypes (used in SaveSLICE6Associations)
  • Model Layer: Model.Hardware (internal namespace, used for persistence, conversion, validation, and uniqueness checks).

Consumed By:

  • IAddEditHardwareView (XAML view) binds to this view model.
  • Other modules (e.g., HardwareListViewModel) may call SetSLICE6TreeView(...) to wire SLICE6 tree integration.
  • Event subscribers for PageModifiedEvent, PageErrorEvent, HardwareSavedEvent.

5. Gotchas

  • Dual constructors: The parameterless constructor is required for XAML but leaves dependencies (_eventAggregator, _regionManager, etc.) uninitialized. Calling methods like Activated() or SetHardware(...) without prior injection may cause NullReferenceException.
  • GetISOHardware() mutates state: If StandIn is true and SerialNumber is not a GUID, it modifies Hardware.SerialNumber and isoHW.SerialNumber in-place. This side effect is not obvious from the method name.
  • Validate(...) only checks uniqueness on add: CheckUniqueSN is skipped during edit (IsAdd == false), even if the serial number was changed.
  • SLICE6TreeViewModel.LoadTreeView(...) is called on Hardware setter: This may trigger expensive tree reloads even when Hardware is set to the same instance (e.g., via property binding updates).
  • NotificationsOn defaults to false: NotifyModified() does nothing unless explicitly enabled. This may lead to missed “page modified” signals if forgotten.
  • OnRaiseNotification strips title from NotificationContentEventArgs: The original eventArgsWithTitle.Title is used as the popup title, but the message content is reconstructed with an empty string for the third parameter (likely legacy or for compatibility).
  • No-op lifecycle methods: Initialize, Cleanup, etc., are present but empty. Developers may assume they do work; they do not.
  • IsAdd is not stored in the view model: It is passed only to Validate(...) and Save(...). If the view model is reused across multiple add/edit operations, IsAdd must be tracked externally (e.g., via parameter or model.IsAdd).

None identified beyond the above.