diff --git a/Terminal.Gui/Views/Dialog.cs b/Terminal.Gui/Views/Dialog.cs
index 1a5b4b362..0d9da0bdc 100644
--- a/Terminal.Gui/Views/Dialog.cs
+++ b/Terminal.Gui/Views/Dialog.cs
@@ -7,13 +7,21 @@ namespace Terminal.Gui.Views;
/// scheme.
///
///
-/// To run the modally, create the , and pass it to
-/// . This will execute the dialog until
-/// it terminates via the (`Esc` by default),
-/// or when one of the views or buttons added to the dialog calls
-/// .
+///
+/// To run the modally, create the , and pass it to
+/// . This will execute the dialog until
+/// it terminates via the (`Esc` by default),
+/// or when one of the views or buttons added to the dialog calls
+/// .
+///
+///
+/// Phase 2: now implements with
+/// int? as the result type, returning the index of the clicked button. The
+/// property replaces the need for manual result tracking. A result of indicates
+/// the dialog was canceled (ESC pressed, window closed without clicking a button).
+///
///
-public class Dialog : Window
+public class Dialog : Window, IRunnable
{
///
/// Initializes a new instance of the class with no s.
@@ -85,7 +93,13 @@ public class Dialog : Window
}
/// Gets a value indicating whether the was canceled.
- /// The default value is .
+ ///
+ /// The default value is .
+ ///
+ /// Deprecated: Use instead. This property is maintained for backward
+ /// compatibility. A indicates the dialog was canceled.
+ ///
+ ///
public bool Canceled
{
get { return _canceled; }
@@ -101,6 +115,21 @@ public class Dialog : Window
}
}
+ ///
+ /// Gets or sets the result data extracted when the dialog was accepted, or if not accepted.
+ ///
+ ///
+ ///
+ /// Returns the zero-based index of the button that was clicked, or if the
+ /// dialog was canceled (ESC pressed, window closed without clicking a button).
+ ///
+ ///
+ /// This property is automatically set in when the dialog is
+ /// closing. The result is extracted by finding which button has focus when the dialog stops.
+ ///
+ ///
+ public int? Result { get; set; }
+
///
/// Defines the default border styling for . Can be configured via
/// .
@@ -168,4 +197,67 @@ public class Dialog : Window
return false;
}
+
+ #region IRunnable Implementation
+
+ ///
+ /// Called when the dialog is about to stop running. Extracts the button result before the dialog is removed
+ /// from the runnable stack.
+ ///
+ /// The current value of IsRunning.
+ /// The new value of IsRunning (true = starting, false = stopping).
+ /// to cancel; to proceed.
+ ///
+ /// This method is called by the IRunnable infrastructure when the dialog is stopping. It extracts
+ /// which button was clicked (if any) before views are disposed.
+ ///
+ protected virtual bool OnIsRunningChanging (bool oldIsRunning, bool newIsRunning)
+ {
+ if (!newIsRunning && oldIsRunning) // Stopping
+ {
+ // Extract result BEFORE disposal - find which button has focus or was last clicked
+ Result = null; // Default: canceled (null = no button clicked)
+
+ for (var i = 0; i < _buttons.Count; i++)
+ {
+ if (_buttons [i].HasFocus)
+ {
+ Result = i;
+ _canceled = false;
+ break;
+ }
+ }
+
+ // If no button has focus, check if any button was the last focused view
+ if (Result is null && MostFocused is Button btn && _buttons.Contains (btn))
+ {
+ Result = _buttons.IndexOf (btn);
+ _canceled = false;
+ }
+
+ // Update legacy Canceled property for backward compatibility
+ if (Result is null)
+ {
+ _canceled = true;
+ }
+ }
+ else if (newIsRunning) // Starting
+ {
+ // Clear result when starting
+ Result = null;
+ _canceled = true; // Default to canceled until a button is clicked
+ }
+
+ // Call base implementation (Toplevel.IRunnable.RaiseIsRunningChanging)
+ return ((IRunnable)this).RaiseIsRunningChanging (oldIsRunning, newIsRunning);
+ }
+
+ // Explicitly implement IRunnable to override the behavior from Toplevel's IRunnable
+ bool IRunnable.RaiseIsRunningChanging (bool oldIsRunning, bool newIsRunning)
+ {
+ // Call our virtual method so subclasses can override
+ return OnIsRunningChanging (oldIsRunning, newIsRunning);
+ }
+
+ #endregion
}