Browse Source

Phase 2: Create IRunnable infrastructure

Co-authored-by: tig <[email protected]>
copilot-swe-agent[bot] 3 weeks ago
parent
commit
0c6de9f9f3

+ 52 - 0
Terminal.Gui/App/IModalRunnable.cs

@@ -0,0 +1,52 @@
+namespace Terminal.Gui.App;
+
+/// <summary>
+/// Defines a runnable view that captures exclusive input (modal behavior) and returns a result.
+/// </summary>
+/// <typeparam name="TResult">
+/// The type of result data returned when the modal is accepted.
+/// Common types: <see cref="int"/> for button indices, <see cref="string"/> for file paths,
+/// custom types for complex form data.
+/// </typeparam>
+/// <remarks>
+/// <para>
+/// Modal runnables block execution of <see cref="IApplication.Run"/> until stopped,
+/// capture all keyboard and mouse input exclusively, and typically have elevated Z-order.
+/// </para>
+/// <para>
+/// When <see cref="Result"/> is <c>null</c>, the modal was stopped without being accepted
+/// (e.g., ESC key pressed, window closed). When non-<c>null</c>, it contains the result data
+/// that was extracted from the Accept command before the modal's subviews were disposed.
+/// </para>
+/// <para>
+/// Common implementations include <see cref="Dialog"/>, <see cref="MessageBox"/>, and <see cref="Wizard"/>.
+/// </para>
+/// <para>
+/// For modals that need to provide additional context or data upon completion, populate the result
+/// before setting it. By default (except for <see cref="Button"/>s with <see cref="Button.IsDefault"/> set),
+/// if a modal does not handle the Accept command, <see cref="Result"/> will be null (canceled).
+/// </para>
+/// </remarks>
+public interface IModalRunnable<TResult> : IRunnable
+{
+    /// <summary>
+    /// Gets the result data from the modal operation, or <c>null</c> if not accepted.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// Implementations should set this property when the modal is accepted (e.g., OK button clicked,
+    /// file selected). The result should be extracted from the modal's state before views are disposed.
+    /// </para>
+    /// <para>
+    /// <c>null</c> indicates the modal was stopped without accepting (ESC key, cancel button, close without action).
+    /// Non-<c>null</c> contains the type-safe result data.
+    /// </para>
+    /// <para>
+    /// For example:
+    /// - <see cref="Dialog"/>: Returns button index (int) or custom result
+    /// - <see cref="MessageBox"/>: Returns button index (int)
+    /// - <see cref="FileDialog"/>: Returns selected file path (string)
+    /// </para>
+    /// </remarks>
+    TResult? Result { get; set; }
+}

+ 201 - 0
Terminal.Gui/App/IRunnable.cs

@@ -0,0 +1,201 @@
+namespace Terminal.Gui.App;
+
+/// <summary>
+/// Defines a view that can be run as an independent session with <see cref="IApplication.Run"/>.
+/// </summary>
+/// <remarks>
+/// <para>
+/// A runnable view can execute as a self-contained session with its own lifecycle,
+/// event loop iteration, and focus management.
+/// </para>
+/// <para>
+/// Implementing <see cref="IRunnable"/> does not require any specific view hierarchy
+/// (e.g., deriving from Toplevel) or layout mode (e.g., Overlapped).
+/// </para>
+/// <para>
+/// For exclusive input capture (modal behavior), implement <see cref="IModalRunnable{TResult}"/>.
+/// </para>
+/// <para>
+/// This interface follows the Terminal.Gui Cancellable Work Pattern (CWP) for lifecycle events
+/// where cancellation makes sense (Stopping, Activating, Deactivating).
+/// </para>
+/// </remarks>
+public interface IRunnable
+{
+    /// <summary>
+    /// Gets or sets whether this runnable session is currently running.
+    /// </summary>
+    /// <remarks>
+    /// This property is set by the framework during session lifecycle. Setting this property
+    /// directly is discouraged. Use <see cref="IApplication.RequestStop"/> instead.
+    /// </remarks>
+    bool Running { get; set; }
+
+    #region Lifecycle Methods (Called by IApplication)
+
+    /// <summary>
+    /// Raises the <see cref="Stopping"/> and <see cref="Stopped"/> events.
+    /// Called by <see cref="IApplication.RequestStop"/>.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// This method implements the Cancellable Work Pattern for stopping:
+    /// 1. Calls virtual method (can cancel)
+    /// 2. Raises <see cref="Stopping"/> event (can cancel)
+    /// 3. If not canceled, sets <see cref="Running"/> = false
+    /// 4. Calls post-notification virtual method
+    /// 5. Raises <see cref="Stopped"/> event
+    /// </para>
+    /// <para>
+    /// Implementations should follow this pattern. See <see cref="Runnable"/> for reference implementation.
+    /// </para>
+    /// </remarks>
+    void RaiseStoppingEvent ();
+
+    /// <summary>
+    /// Raises the <see cref="Activating"/> event.
+    /// Called by <see cref="IApplication.Begin"/> when this runnable is becoming the active session.
+    /// </summary>
+    /// <param name="deactivated">The previously active runnable being deactivated, or null if none.</param>
+    /// <returns><see langword="true"/> if activation was canceled; otherwise <see langword="false"/>.</returns>
+    /// <remarks>
+    /// <para>
+    /// This method implements the Cancellable Work Pattern for activation:
+    /// 1. Calls virtual method (can cancel)
+    /// 2. Raises <see cref="Activating"/> event (can cancel)
+    /// 3. If canceled, returns true
+    /// 4. If not canceled, calls <see cref="RaiseActivatedEvent"/> and returns false
+    /// </para>
+    /// </remarks>
+    bool RaiseActivatingEvent (IRunnable? deactivated);
+
+    /// <summary>
+    /// Raises the <see cref="Activated"/> event.
+    /// Called by <see cref="RaiseActivatingEvent"/> after activation succeeds.
+    /// </summary>
+    /// <param name="deactivated">The previously active runnable that was deactivated, or null if none.</param>
+    /// <remarks>
+    /// This is the post-notification phase of activation. Implementations should raise the
+    /// <see cref="Activated"/> event.
+    /// </remarks>
+    void RaiseActivatedEvent (IRunnable? deactivated);
+
+    /// <summary>
+    /// Raises the <see cref="Deactivating"/> event.
+    /// Called by <see cref="IApplication.Begin"/> when switching to a new runnable.
+    /// </summary>
+    /// <param name="activated">The newly activated runnable, or null if none.</param>
+    /// <returns><see langword="true"/> if deactivation was canceled; otherwise <see langword="false"/>.</returns>
+    /// <remarks>
+    /// <para>
+    /// This method implements the Cancellable Work Pattern for deactivation:
+    /// 1. Calls virtual method (can cancel)
+    /// 2. Raises <see cref="Deactivating"/> event (can cancel)
+    /// 3. If canceled, returns true
+    /// 4. If not canceled, calls <see cref="RaiseDeactivatedEvent"/> and returns false
+    /// </para>
+    /// </remarks>
+    bool RaiseDeactivatingEvent (IRunnable? activated);
+
+    /// <summary>
+    /// Raises the <see cref="Deactivated"/> event.
+    /// Called by <see cref="RaiseDeactivatingEvent"/> after deactivation succeeds.
+    /// </summary>
+    /// <param name="activated">The newly activated runnable, or null if none.</param>
+    /// <remarks>
+    /// This is the post-notification phase of deactivation. Implementations should raise the
+    /// <see cref="Deactivated"/> event.
+    /// </remarks>
+    void RaiseDeactivatedEvent (IRunnable? activated);
+
+    #endregion
+
+    #region Lifecycle Events
+
+    /// <summary>
+    /// Raised during <see cref="ISupportInitialize.EndInit"/> before initialization completes.
+    /// Can be canceled by setting <see cref="System.ComponentModel.CancelEventArgs.Cancel"/> to <see langword="true"/>.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// This event is from the <see cref="ISupportInitialize"/> pattern and is raised by <see cref="View.EndInit"/>.
+    /// Subscribe to this event to perform pre-initialization work or to cancel initialization.
+    /// </para>
+    /// <para>
+    /// This event follows the Terminal.Gui Cancellable Work Pattern.
+    /// </para>
+    /// </remarks>
+    event EventHandler<System.ComponentModel.CancelEventArgs>? Initializing;
+
+    /// <summary>
+    /// Raised after the runnable has been initialized (via <see cref="ISupportInitialize.BeginInit"/>/<see cref="ISupportInitialize.EndInit"/>).
+    /// The view is laid out and ready to be drawn.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// This event is from the <see cref="ISupportInitialize"/> pattern and is raised by <see cref="View.EndInit"/>.
+    /// Subscribe to this event to perform initialization that requires the view to be fully laid out.
+    /// </para>
+    /// <para>
+    /// This is the post-notification event in the Cancellable Work Pattern pair with <see cref="Initializing"/>.
+    /// </para>
+    /// </remarks>
+    event EventHandler? Initialized;
+
+    /// <summary>
+    /// Raised when <see cref="IApplication.RequestStop"/> is called on this runnable.
+    /// Can be canceled by setting <see cref="System.ComponentModel.CancelEventArgs.Cancel"/> to <see langword="true"/>.
+    /// </summary>
+    /// <remarks>
+    /// Subscribe to this event to prevent the runnable from stopping (e.g., to prompt the user
+    /// to save changes). If canceled, <see cref="Running"/> will remain <see langword="true"/>.
+    /// </remarks>
+    event EventHandler<System.ComponentModel.CancelEventArgs>? Stopping;
+
+    /// <summary>
+    /// Raised after the runnable session has stopped (<see cref="Running"/> = <see langword="false"/>).
+    /// </summary>
+    /// <remarks>
+    /// This is the post-notification event in the Cancellable Work Pattern pair with <see cref="Stopping"/>.
+    /// Subscribe to this event for cleanup work that should occur after the session stops.
+    /// </remarks>
+    event EventHandler? Stopped;
+
+    /// <summary>
+    /// Raised when the runnable session is about to become active (the current session).
+    /// Can be canceled by setting <see cref="RunnableActivatingEventArgs.Cancel"/> to <see langword="true"/>.
+    /// </summary>
+    /// <remarks>
+    /// Subscribe to this event to prevent activation or to perform pre-activation work.
+    /// </remarks>
+    event EventHandler<RunnableActivatingEventArgs>? Activating;
+
+    /// <summary>
+    /// Raised when the runnable session has become active.
+    /// </summary>
+    /// <remarks>
+    /// This is the post-notification event in the Cancellable Work Pattern pair with <see cref="Activating"/>.
+    /// Subscribe to this event for post-activation logic (e.g., setting focus).
+    /// </remarks>
+    event EventHandler<RunnableEventArgs>? Activated;
+
+    /// <summary>
+    /// Raised when the runnable session is about to cease being active (another session is activating).
+    /// Can be canceled by setting <see cref="RunnableDeactivatingEventArgs.Cancel"/> to <see langword="true"/>.
+    /// </summary>
+    /// <remarks>
+    /// Subscribe to this event to prevent deactivation or to perform pre-deactivation work.
+    /// </remarks>
+    event EventHandler<RunnableDeactivatingEventArgs>? Deactivating;
+
+    /// <summary>
+    /// Raised when the runnable session has ceased being active.
+    /// </summary>
+    /// <remarks>
+    /// This is the post-notification event in the Cancellable Work Pattern pair with <see cref="Deactivating"/>.
+    /// Subscribe to this event for cleanup or state preservation after deactivation.
+    /// </remarks>
+    event EventHandler<RunnableEventArgs>? Deactivated;
+
+    #endregion
+}

+ 87 - 0
Terminal.Gui/App/RunnableEventArgs.cs

@@ -0,0 +1,87 @@
+namespace Terminal.Gui.App;
+
+/// <summary>
+/// Event args for <see cref="IRunnable"/> lifecycle events that provide information about the runnable.
+/// </summary>
+/// <remarks>
+/// Used for post-notification events that cannot be canceled:
+/// <see cref="IRunnable.Activated"/> and <see cref="IRunnable.Deactivated"/>.
+/// </remarks>
+public class RunnableEventArgs : EventArgs
+{
+    /// <summary>
+    /// Initializes a new instance of <see cref="RunnableEventArgs"/>.
+    /// </summary>
+    /// <param name="runnable">The runnable involved in the event.</param>
+    public RunnableEventArgs (IRunnable runnable)
+    {
+        Runnable = runnable;
+    }
+
+    /// <summary>
+    /// Gets the runnable involved in the event.
+    /// </summary>
+    public IRunnable Runnable { get; }
+}
+
+/// <summary>
+/// Event args for <see cref="IRunnable.Activating"/> event. Allows cancellation.
+/// </summary>
+/// <remarks>
+/// This event is raised when a runnable session is about to become active. It can be canceled
+/// by setting <see cref="System.ComponentModel.CancelEventArgs.Cancel"/> to <see langword="true"/>.
+/// </remarks>
+public class RunnableActivatingEventArgs : System.ComponentModel.CancelEventArgs
+{
+    /// <summary>
+    /// Initializes a new instance of <see cref="RunnableActivatingEventArgs"/>.
+    /// </summary>
+    /// <param name="activating">The runnable that is being activated.</param>
+    /// <param name="deactivated">The runnable that is being deactivated, or null if none.</param>
+    public RunnableActivatingEventArgs (IRunnable activating, IRunnable? deactivated)
+    {
+        Activating = activating;
+        Deactivated = deactivated;
+    }
+
+    /// <summary>
+    /// Gets the runnable that is being activated.
+    /// </summary>
+    public IRunnable Activating { get; }
+
+    /// <summary>
+    /// Gets the runnable that is being deactivated, or null if none.
+    /// </summary>
+    public IRunnable? Deactivated { get; }
+}
+
+/// <summary>
+/// Event args for <see cref="IRunnable.Deactivating"/> event. Allows cancellation.
+/// </summary>
+/// <remarks>
+/// This event is raised when a runnable session is about to cease being active. It can be canceled
+/// by setting <see cref="System.ComponentModel.CancelEventArgs.Cancel"/> to <see langword="true"/>.
+/// </remarks>
+public class RunnableDeactivatingEventArgs : System.ComponentModel.CancelEventArgs
+{
+    /// <summary>
+    /// Initializes a new instance of <see cref="RunnableDeactivatingEventArgs"/>.
+    /// </summary>
+    /// <param name="deactivating">The runnable that is being deactivated.</param>
+    /// <param name="activated">The runnable that is being activated, or null if none.</param>
+    public RunnableDeactivatingEventArgs (IRunnable deactivating, IRunnable? activated)
+    {
+        Deactivating = deactivating;
+        Activated = activated;
+    }
+
+    /// <summary>
+    /// Gets the runnable that is being deactivated.
+    /// </summary>
+    public IRunnable Deactivating { get; }
+
+    /// <summary>
+    /// Gets the runnable that is being activated, or null if none.
+    /// </summary>
+    public IRunnable? Activated { get; }
+}

+ 277 - 0
Terminal.Gui/ViewBase/Runnable.cs

@@ -0,0 +1,277 @@
+namespace Terminal.Gui.ViewBase;
+
+/// <summary>
+/// Base implementation of <see cref="IRunnable"/> for views that can be run as sessions.
+/// </summary>
+/// <remarks>
+/// <para>
+/// Views can derive from this class or implement <see cref="IRunnable"/> directly.
+/// This base class provides a complete reference implementation of the <see cref="IRunnable"/>
+/// interface following Terminal.Gui's Cancellable Work Pattern.
+/// </para>
+/// <para>
+/// To customize lifecycle behavior, override the protected virtual methods:
+/// <see cref="OnStopping"/>, <see cref="OnStopped"/>, <see cref="OnActivating"/>,
+/// <see cref="OnActivated"/>, <see cref="OnDeactivating"/>, <see cref="OnDeactivated"/>.
+/// </para>
+/// </remarks>
+public class Runnable : View, IRunnable
+{
+    /// <inheritdoc/>
+    public bool Running { get; set; }
+
+    #region IRunnable Implementation (RaiseXxxEvent Methods)
+
+    /// <inheritdoc/>
+    public virtual void RaiseStoppingEvent ()
+    {
+        // CWP Phase 1: Pre-notification via virtual method (can cancel)
+        if (OnStopping ())
+        {
+            return; // Stopping canceled
+        }
+
+        // CWP Phase 2: Event notification (can cancel)
+        var args = new System.ComponentModel.CancelEventArgs ();
+        Stopping?.Invoke (this, args);
+
+        if (args.Cancel)
+        {
+            return; // Stopping canceled
+        }
+
+        // CWP Phase 3: Perform the work (stop the session)
+        Running = false;
+
+        // CWP Phase 4: Post-notification via virtual method
+        OnStopped ();
+
+        // CWP Phase 5: Post-notification event
+        Stopped?.Invoke (this, EventArgs.Empty);
+    }
+
+    /// <inheritdoc/>
+    public virtual bool RaiseActivatingEvent (IRunnable? deactivated)
+    {
+        // CWP Phase 1: Pre-notification via virtual method (can cancel)
+        if (OnActivating (deactivated))
+        {
+            return true; // Activation canceled
+        }
+
+        // CWP Phase 2: Event notification (can cancel)
+        var args = new RunnableActivatingEventArgs (this, deactivated);
+        Activating?.Invoke (this, args);
+
+        if (args.Cancel)
+        {
+            return true; // Activation canceled
+        }
+
+        // CWP Phase 3: Work is done by Application (setting Current)
+        // CWP Phase 4 & 5: Call post-notification methods
+        OnActivated (deactivated);
+
+        return false; // Activation succeeded
+    }
+
+    /// <inheritdoc/>
+    public virtual void RaiseActivatedEvent (IRunnable? deactivated)
+    {
+        Activated?.Invoke (this, new RunnableEventArgs (this));
+    }
+
+    /// <inheritdoc/>
+    public virtual bool RaiseDeactivatingEvent (IRunnable? activated)
+    {
+        // CWP Phase 1: Pre-notification via virtual method (can cancel)
+        if (OnDeactivating (activated))
+        {
+            return true; // Deactivation canceled
+        }
+
+        // CWP Phase 2: Event notification (can cancel)
+        var args = new RunnableDeactivatingEventArgs (this, activated);
+        Deactivating?.Invoke (this, args);
+
+        if (args.Cancel)
+        {
+            return true; // Deactivation canceled
+        }
+
+        // CWP Phase 3: Work is done by Application (changing Current)
+        // CWP Phase 4 & 5: Call post-notification methods
+        OnDeactivated (activated);
+
+        return false; // Deactivation succeeded
+    }
+
+    /// <inheritdoc/>
+    public virtual void RaiseDeactivatedEvent (IRunnable? activated)
+    {
+        Deactivated?.Invoke (this, new RunnableEventArgs (this));
+    }
+
+    #endregion
+
+    #region Protected Virtual Methods (Override Pattern)
+
+    /// <summary>
+    /// Called before <see cref="Stopping"/> event. Override to cancel stopping.
+    /// </summary>
+    /// <returns><see langword="true"/> to cancel; <see langword="false"/> to proceed.</returns>
+    /// <remarks>
+    /// <para>
+    /// This is the first phase of the Cancellable Work Pattern for stopping.
+    /// Default implementation returns <see langword="false"/> (allow stopping).
+    /// </para>
+    /// <para>
+    /// Override this method to provide custom logic for determining whether the runnable
+    /// should stop (e.g., prompting the user to save changes).
+    /// </para>
+    /// </remarks>
+    protected virtual bool OnStopping ()
+    {
+        return false; // Default: allow stopping
+    }
+
+    /// <summary>
+    /// Called after session has stopped. Override for post-stop cleanup.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// This is the fourth phase of the Cancellable Work Pattern for stopping.
+    /// At this point, <see cref="Running"/> is <see langword="false"/>.
+    /// Default implementation does nothing.
+    /// </para>
+    /// <para>
+    /// Override this method to perform cleanup work that should occur after the session stops.
+    /// </para>
+    /// </remarks>
+    protected virtual void OnStopped ()
+    {
+        // Default: do nothing
+    }
+
+    /// <summary>
+    /// Called before <see cref="Activating"/> event. Override to cancel activation.
+    /// </summary>
+    /// <param name="deactivated">The previously active runnable being deactivated, or null if none.</param>
+    /// <returns><see langword="true"/> to cancel; <see langword="false"/> to proceed.</returns>
+    /// <remarks>
+    /// <para>
+    /// This is the first phase of the Cancellable Work Pattern for activation.
+    /// Default implementation returns <see langword="false"/> (allow activation).
+    /// </para>
+    /// <para>
+    /// Override this method to provide custom logic for determining whether the runnable
+    /// should become active.
+    /// </para>
+    /// </remarks>
+    protected virtual bool OnActivating (IRunnable? deactivated)
+    {
+        return false; // Default: allow activation
+    }
+
+    /// <summary>
+    /// Called after activation succeeds. Override for post-activation logic.
+    /// </summary>
+    /// <param name="deactivated">The previously active runnable that was deactivated, or null if none.</param>
+    /// <remarks>
+    /// <para>
+    /// This is the fourth phase of the Cancellable Work Pattern for activation.
+    /// Default implementation calls <see cref="RaiseActivatedEvent"/>.
+    /// </para>
+    /// <para>
+    /// Override this method to perform work that should occur after activation
+    /// (e.g., setting focus, updating UI). Overrides must call base to ensure the
+    /// <see cref="Activated"/> event is raised.
+    /// </para>
+    /// </remarks>
+    protected virtual void OnActivated (IRunnable? deactivated)
+    {
+        RaiseActivatedEvent (deactivated);
+    }
+
+    /// <summary>
+    /// Called before <see cref="Deactivating"/> event. Override to cancel deactivation.
+    /// </summary>
+    /// <param name="activated">The newly activated runnable, or null if none.</param>
+    /// <returns><see langword="true"/> to cancel; <see langword="false"/> to proceed.</returns>
+    /// <remarks>
+    /// <para>
+    /// This is the first phase of the Cancellable Work Pattern for deactivation.
+    /// Default implementation returns <see langword="false"/> (allow deactivation).
+    /// </para>
+    /// <para>
+    /// Override this method to provide custom logic for determining whether the runnable
+    /// should be deactivated (e.g., preventing switching away if unsaved changes exist).
+    /// </para>
+    /// </remarks>
+    protected virtual bool OnDeactivating (IRunnable? activated)
+    {
+        return false; // Default: allow deactivation
+    }
+
+    /// <summary>
+    /// Called after deactivation succeeds. Override for post-deactivation logic.
+    /// </summary>
+    /// <param name="activated">The newly activated runnable, or null if none.</param>
+    /// <remarks>
+    /// <para>
+    /// This is the fourth phase of the Cancellable Work Pattern for deactivation.
+    /// Default implementation calls <see cref="RaiseDeactivatedEvent"/>.
+    /// </para>
+    /// <para>
+    /// Override this method to perform work that should occur after deactivation
+    /// (e.g., saving state, releasing resources). Overrides must call base to ensure the
+    /// <see cref="Deactivated"/> event is raised.
+    /// </para>
+    /// </remarks>
+    protected virtual void OnDeactivated (IRunnable? activated)
+    {
+        RaiseDeactivatedEvent (activated);
+    }
+
+    #endregion
+
+    #region Events
+
+    // Note: Initializing and Initialized events are inherited from View (ISupportInitialize pattern)
+
+    /// <inheritdoc/>
+    public event EventHandler<System.ComponentModel.CancelEventArgs>? Stopping;
+
+    /// <inheritdoc/>
+    public event EventHandler? Stopped;
+
+    /// <inheritdoc/>
+    public event EventHandler<RunnableActivatingEventArgs>? Activating;
+
+    /// <inheritdoc/>
+    public event EventHandler<RunnableEventArgs>? Activated;
+
+    /// <inheritdoc/>
+    public event EventHandler<RunnableDeactivatingEventArgs>? Deactivating;
+
+    /// <inheritdoc/>
+    public event EventHandler<RunnableEventArgs>? Deactivated;
+
+    #endregion
+
+    /// <summary>
+    /// Stops and closes this runnable session.
+    /// </summary>
+    /// <remarks>
+    /// <para>
+    /// This method calls <see cref="RaiseStoppingEvent"/> to initiate the stopping process.
+    /// The Application infrastructure will update this once IApplication supports IRunnable directly.
+    /// </para>
+    /// </remarks>
+    public virtual void RequestStop ()
+    {
+        // TODO: Phase 3 - Update Application.RequestStop to accept IRunnable
+        // For now, directly call RaiseStoppingEvent which follows CWP
+        RaiseStoppingEvent ();
+    }
+}

+ 3 - 3
Terminal.Gui/ViewBase/View.cs

@@ -190,7 +190,7 @@ public partial class View : IDisposable, ISupportInitializeNotification
 
     /// <summary>
     ///     Raised during <see cref="EndInit"/> before initialization completes. Can be canceled by setting
-    ///     <see cref="CancelEventArgs.Cancel"/> to <see langword="true"/>. Follows the Cancellable Work Pattern (CWP).
+    ///     <see cref="System.ComponentModel.CancelEventArgs.Cancel"/> to <see langword="true"/>. Follows the Cancellable Work Pattern (CWP).
     /// </summary>
     /// <remarks>
     ///     <para>
@@ -207,7 +207,7 @@ public partial class View : IDisposable, ISupportInitializeNotification
     ///         5. <see cref="Initialized"/> event
     ///     </para>
     /// </remarks>
-    public event EventHandler<CancelEventArgs>? Initializing;
+    public event EventHandler<System.ComponentModel.CancelEventArgs>? Initializing;
 
     /// <summary>
     ///     Raised once when the <see cref="View"/> has been initialized for the first time. Allows
@@ -305,7 +305,7 @@ public partial class View : IDisposable, ISupportInitializeNotification
         }
 
         // CWP Phase 2: Event notification (can cancel)
-        var args = new CancelEventArgs ();
+        var args = new System.ComponentModel.CancelEventArgs ();
         Initializing?.Invoke (this, args);
 
         if (args.Cancel)