namespace Terminal.Gui.ViewBase; /// /// Wraps any to make it runnable with a typed result, similar to how /// wraps . /// /// The type of view being wrapped. /// The type of result data returned when the session completes. /// /// /// This class enables any View to be run as a blocking session with /// /// without requiring the View to implement or derive from /// . /// /// /// Use for a fluent API approach, /// or to run directly. /// /// /// /// // Wrap a TextField to make it runnable with string result /// var textField = new TextField { Width = 40 }; /// var runnable = new RunnableWrapper<TextField, string> { WrappedView = textField }; /// /// // Extract result when stopping /// runnable.IsRunningChanging += (s, e) => /// { /// if (!e.NewValue) // Stopping /// { /// runnable.Result = runnable.WrappedView.Text; /// } /// }; /// /// app.Run(runnable); /// Console.WriteLine($"User entered: {runnable.Result}"); /// runnable.Dispose(); /// /// /// public class RunnableWrapper : Runnable where TView : View { /// /// Initializes a new instance of . /// public RunnableWrapper () { // Make the wrapper automatically size to fit the wrapped view Width = Dim.Fill (); Height = Dim.Fill (); } private TView? _wrappedView; /// /// Gets or sets the wrapped view that is being made runnable. /// /// /// /// This property must be set before the wrapper is initialized. /// Access this property to interact with the original view, extract its state, /// or configure result extraction logic. /// /// /// Thrown if the property is set after initialization. public required TView WrappedView { get => _wrappedView ?? throw new InvalidOperationException ("WrappedView must be set before use."); init { if (IsInitialized) { throw new InvalidOperationException ("WrappedView cannot be changed after initialization."); } _wrappedView = value; } } /// public override void EndInit () { base.EndInit (); // Add the wrapped view as a subview after initialization if (_wrappedView is { }) { Add (_wrappedView); } } }