From 2cbd94fee7bf6aac72481ed4aa124567311df77e Mon Sep 17 00:00:00 2001 From: Sachin Kumar Date: Wed, 4 Feb 2026 07:15:59 +0530 Subject: [PATCH] =?UTF-8?q?Fix=20#1978=20=E2=80=94=20Add=20XML=20documenta?= =?UTF-8?q?tion=20for=20core=20MVVM=20and=20dialog=20APIs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Prism.Core/Dialogs/IDialogAware.cs | 32 ++++++++++++++++-- src/Prism.Core/IActiveAware.cs | 20 +++++++++++ src/Prism.Core/Mvvm/BindableBase.cs | 26 +++++++++++++++ src/Prism.Core/Mvvm/ErrorsContainer.cs | 28 ++++++++++++++-- src/Wpf/Prism.Wpf/Dialogs/DialogService.cs | 39 ++++++++++++++++++---- 5 files changed, 134 insertions(+), 11 deletions(-) diff --git a/src/Prism.Core/Dialogs/IDialogAware.cs b/src/Prism.Core/Dialogs/IDialogAware.cs index 6b8574a546..90ad409810 100644 --- a/src/Prism.Core/Dialogs/IDialogAware.cs +++ b/src/Prism.Core/Dialogs/IDialogAware.cs @@ -3,28 +3,54 @@ namespace Prism.Dialogs; /// /// Provides a way for objects involved in Dialogs to be notified of Dialog activities. /// -public interface IDialogAware +/// +/// +/// is the primary interface that Dialog ViewModels should implement. +/// It allows ViewModels to participate in the dialog lifecycle and control when dialogs can be closed. +/// +/// +/// Dialog services will automatically call the methods on this interface at appropriate points +/// in the dialog lifecycle (when opened, when closed, before closing to check if closing is allowed). +/// +/// + public interface IDialogAware { /// /// Evaluates whether the Dialog is in a state that would allow the Dialog to Close /// - /// true if the Dialog can close + /// if the Dialog can close; otherwise, + /// + /// This method is called before the dialog is closed. If it returns , the close operation is cancelled. + /// Use this to prevent users from closing a dialog while operations are in progress or when validation fails. + /// bool CanCloseDialog(); /// /// Provides a callback to clean up resources or finalize tasks when the Dialog has been closed /// + /// + /// This method is called after the dialog window has closed. Use it to clean up any resources + /// or perform final actions related to the dialog. + /// void OnDialogClosed(); /// /// Initializes the state of the Dialog with provided DialogParameters /// - /// + /// Dialog parameters passed when showing the dialog + /// + /// This method is called after the dialog is displayed but before it is shown to the user. + /// Use it to initialize the dialog's state based on the provided parameters. + /// void OnDialogOpened(IDialogParameters parameters); /// /// The will be set by the and can be called to /// invoke the close of the Dialog. /// + /// + /// This listener is set by the dialog service and allows the ViewModel to request that the dialog be closed, + /// optionally with a result that indicates the outcome of the dialog (OK, Cancel, etc.). + /// DialogCloseListener RequestClose { get; } } diff --git a/src/Prism.Core/IActiveAware.cs b/src/Prism.Core/IActiveAware.cs index 7ccae52edc..9a0e5d65f2 100644 --- a/src/Prism.Core/IActiveAware.cs +++ b/src/Prism.Core/IActiveAware.cs @@ -6,17 +6,37 @@ namespace Prism /// Interface that defines if the object instance is active /// and notifies when the activity changes. /// + /// + /// + /// The interface is used to track the active state of objects within Prism, + /// particularly in regions. When a view or module becomes active or inactive, implementations of this interface + /// can respond to the state change through the event. + /// + /// + /// This is commonly used for ViewModels that need to load or unload data based on whether their corresponding + /// view is currently being displayed in a region. + /// + /// public interface IActiveAware { /// /// Gets or sets a value indicating whether the object is active. /// /// if the object is active; otherwise . + /// + /// When this property is set to , the object is considered active and should perform + /// any necessary initialization or load operations. When set to , the object should + /// perform cleanup operations. + /// bool IsActive { get; set; } /// /// Notifies that the value for property has changed. /// + /// + /// This event is raised whenever the property value changes, allowing listeners + /// to respond to activation and deactivation events. + /// event EventHandler IsActiveChanged; } } diff --git a/src/Prism.Core/Mvvm/BindableBase.cs b/src/Prism.Core/Mvvm/BindableBase.cs index 4c41912793..91be8dc062 100644 --- a/src/Prism.Core/Mvvm/BindableBase.cs +++ b/src/Prism.Core/Mvvm/BindableBase.cs @@ -7,6 +7,17 @@ namespace Prism.Mvvm /// /// Implementation of to simplify models. /// + /// + /// + /// is a base class designed for ViewModel classes in MVVM applications. + /// It provides a convenient implementation of that reduces boilerplate code + /// when creating ViewModels that need to notify views of property changes. + /// + /// + /// The class provides helper methods like that automatically + /// handle equality comparison and notification, ensuring that listeners are only notified when values actually change. + /// + /// public abstract class BindableBase : INotifyPropertyChanged { /// @@ -26,6 +37,10 @@ public abstract class BindableBase : INotifyPropertyChanged /// support CallerMemberName. /// True if the value was changed, false if the existing value matched the /// desired value. + /// + /// This method uses to compare the current storage value with the new value. + /// Only if they differ will the property be updated and listeners notified. + /// protected virtual bool SetProperty(ref T storage, T value, [CallerMemberName] string? propertyName = null) { if (EqualityComparer.Default.Equals(storage, value)) return false; @@ -49,6 +64,10 @@ protected virtual bool SetProperty(ref T storage, T value, [CallerMemberName] /// Action that is called after the property value has been changed. /// True if the value was changed, false if the existing value matched the /// desired value. + /// + /// This method is useful when you need to perform additional logic when a property changes, + /// such as recalculating a derived property or triggering a command. + /// protected virtual bool SetProperty(ref T storage, T value, Action? onChanged, [CallerMemberName] string? propertyName = null) { @@ -67,6 +86,10 @@ protected virtual bool SetProperty(ref T storage, T value, Action? onChanged, /// Name of the property used to notify listeners. This /// value is optional and can be provided automatically when invoked from compilers /// that support . + /// + /// This method is typically called automatically by , + /// but can also be called directly to notify of changes to computed properties. + /// protected void RaisePropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); @@ -76,6 +99,9 @@ protected void RaisePropertyChanged([CallerMemberName] string? propertyName = nu /// Raises this object's PropertyChanged event. /// /// The PropertyChangedEventArgs + /// + /// Override this method to intercept property change notifications before they are broadcast to subscribers. + /// protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) { PropertyChanged?.Invoke(this, args); diff --git a/src/Prism.Core/Mvvm/ErrorsContainer.cs b/src/Prism.Core/Mvvm/ErrorsContainer.cs index ad5bbeb864..4960227311 100644 --- a/src/Prism.Core/Mvvm/ErrorsContainer.cs +++ b/src/Prism.Core/Mvvm/ErrorsContainer.cs @@ -6,6 +6,16 @@ namespace Prism.Mvvm /// /// Manages validation errors for an object, notifying when the error state changes. /// + /// + /// + /// is a utility class for ViewModels that need to manage and track validation errors. + /// It implements the pattern, maintaining a collection of errors per property + /// and notifying when the error state changes. + /// + /// + /// This class is typically used with data validation frameworks to maintain error state and notify the UI when validation fails. + /// + /// /// The type of the error object. public class ErrorsContainer { @@ -24,7 +34,8 @@ public class ErrorsContainer /// /// Initializes a new instance of the class. /// - /// The action that is invoked when errors are added for an object. + /// The action that is invoked when errors are added or removed for a property. + /// Thrown when is . public ErrorsContainer(Action raiseErrorsChanged) { if (raiseErrorsChanged == null) @@ -39,6 +50,10 @@ public ErrorsContainer(Action raiseErrorsChanged) /// /// Gets a value indicating whether the object has validation errors. /// + /// if there are any errors; otherwise, . + /// + /// This property returns only if there is at least one error for any property. + /// public bool HasErrors { get @@ -51,13 +66,19 @@ public bool HasErrors /// Returns all the errors in the container. /// /// The dictionary of errors per property. + /// + /// The returned dictionary maps property names to lists of errors for those properties. + /// public Dictionary> GetErrors() => validationResults; /// /// Gets the validation errors for a specified property. /// - /// The name of the property. + /// The name of the property. If or empty, returns errors for the object itself. /// The validation errors of type for the property. + /// + /// If the property has no errors, an empty enumerable is returned. + /// public IEnumerable GetErrors(string? propertyName) { var localPropertyName = propertyName ?? string.Empty; @@ -74,6 +95,9 @@ public IEnumerable GetErrors(string? propertyName) /// /// Clears all errors. /// + /// + /// This removes all errors from all properties and raises the ErrorsChanged event for each property that had errors. + /// public void ClearErrors() { foreach (var key in this.validationResults.Keys.ToArray()) diff --git a/src/Wpf/Prism.Wpf/Dialogs/DialogService.cs b/src/Wpf/Prism.Wpf/Dialogs/DialogService.cs index 90a67e018a..150aa3c7f1 100644 --- a/src/Wpf/Prism.Wpf/Dialogs/DialogService.cs +++ b/src/Wpf/Prism.Wpf/Dialogs/DialogService.cs @@ -7,7 +7,14 @@ namespace Prism.Dialogs /// Implements to show modal and non-modal dialogs. /// /// - /// The dialog's ViewModel must implement IDialogAware. + /// + /// The is responsible for managing the lifecycle of dialog windows in WPF applications. + /// It handles dialog creation, initialization, showing/hiding, and event coordination between the view and view model. + /// + /// + /// The dialog's ViewModel must implement to participate in the dialog lifecycle. + /// Dialog views must also implement or inherit from it. + /// /// public class DialogService : IDialogService { @@ -16,7 +23,7 @@ public class DialogService : IDialogService /// /// Initializes a new instance of the class. /// - /// The + /// The used to resolve dialog views and windows. public DialogService(IContainerExtension containerExtension) { _containerExtension = containerExtension; @@ -25,9 +32,13 @@ public DialogService(IContainerExtension containerExtension) /// /// Shows a modal dialog. /// - /// The name of the dialog to show. - /// The parameters to pass to the dialog. + /// The name of the dialog to show. This name must be registered in the container. + /// The parameters to pass to the dialog's ViewModel. /// The action to perform when the dialog is closed. + /// + /// The dialog can be shown as either modal or non-modal based on the parameter. + /// By default, dialogs are shown as modal (blocking the parent window). + /// public void ShowDialog(string name, IDialogParameters parameters, DialogCallback callback) { parameters ??= new DialogParameters(); @@ -45,7 +56,10 @@ public void ShowDialog(string name, IDialogParameters parameters, DialogCallback /// Shows the dialog window. /// /// The dialog window to show. - /// If true; dialog is shown as a modal + /// If , the dialog is shown as a modal window that blocks interaction with the parent; otherwise, it is shown as a modeless window. + /// + /// This method can be overridden to customize how the dialog window is displayed. + /// protected virtual void ShowDialogWindow(IDialogWindow dialogWindow, bool isModal) { if (isModal) @@ -57,8 +71,11 @@ protected virtual void ShowDialogWindow(IDialogWindow dialogWindow, bool isModal /// /// Create a new . /// - /// The name of the hosting window registered with the IContainerRegistry. + /// The name of the hosting window registered with the IContainerRegistry. If or empty, the default dialog window is used. /// The created . + /// + /// This method can be overridden to customize dialog window creation. + /// protected virtual IDialogWindow CreateDialogWindow(string name) { if (string.IsNullOrWhiteSpace(name)) @@ -73,6 +90,9 @@ protected virtual IDialogWindow CreateDialogWindow(string name) /// The name of the dialog to show. /// The hosting window. /// The parameters to pass to the dialog. + /// + /// This method resolves the dialog content from the container, auto-wires the view model, and initializes the dialog. + /// protected virtual void ConfigureDialogWindowContent(string dialogName, IDialogWindow window, IDialogParameters parameters) { var content = _containerExtension.Resolve(dialogName); @@ -94,6 +114,9 @@ protected virtual void ConfigureDialogWindowContent(string dialogName, IDialogWi /// /// The hosting window. /// The action to perform when the dialog is closed. + /// + /// This method sets up event handlers for the dialog lifecycle including Loaded, Closing, and Closed events. + /// protected virtual void ConfigureDialogWindowEvents(IDialogWindow dialogWindow, DialogCallback callback) { Action requestCloseHandler = (r) => @@ -143,12 +166,16 @@ protected virtual void ConfigureDialogWindowEvents(IDialogWindow dialogWindow, D /// The hosting window. /// The dialog to show. /// The dialog's ViewModel. + /// + /// This method sets up the window style, title, and content based on the dialog view and view model configuration. + /// protected virtual void ConfigureDialogWindowProperties(IDialogWindow window, FrameworkElement dialogContent, IDialogAware viewModel) { var windowStyle = Dialog.GetWindowStyle(dialogContent); if (windowStyle != null) window.Style = windowStyle; + window.Content = dialogContent; window.DataContext = viewModel; //we want the host window and the dialog to share the same data context