#nullable enable namespace Terminal.Gui; /// /// Helper class for implementing . /// /// /// /// Implements the standard pattern for changing/changed events. /// /// /// /// /// private class OrientedView : View, IOrientation /// { /// private readonly OrientationHelper _orientationHelper; /// /// public OrientedView () /// { /// _orientationHelper = new (this); /// Orientation = Orientation.Vertical; /// _orientationHelper.OrientationChanging += (sender, e) => OrientationChanging?.Invoke (this, e); /// _orientationHelper.OrientationChanged += (sender, e) => OrientationChanged?.Invoke (this, e); /// } /// /// public Orientation Orientation /// { /// get => _orientationHelper.Orientation; /// set => _orientationHelper.Orientation = value; /// } /// /// public event EventHandler<CancelEventArgs<Orientation>> OrientationChanging; /// public event EventHandler<EventArgs<Orientation>> OrientationChanged; /// /// public bool OnOrientationChanging (Orientation currentOrientation, Orientation newOrientation) /// { /// // Custom logic before orientation changes /// return false; // Return true to cancel the change /// } /// /// public void OnOrientationChanged (Orientation newOrientation) /// { /// // Custom logic after orientation has changed /// } /// } /// /// public class OrientationHelper { private Orientation _orientation; private readonly IOrientation _owner; /// /// Initializes a new instance of the class. /// /// Specifies the object that owns this helper instance and implements . public OrientationHelper (IOrientation owner) { _owner = owner; } /// /// Gets or sets the orientation of the View. /// public Orientation Orientation { get => _orientation; set { if (_orientation == value) { return; } // Best practice is to invoke the virtual method first. // This allows derived classes to handle the event and potentially cancel it. if (_owner?.OnOrientationChanging (value, _orientation) ?? false) { return; } // If the event is not canceled by the virtual method, raise the event to notify any external subscribers. CancelEventArgs args = new (in _orientation, ref value); OrientationChanging?.Invoke (_owner, args); if (args.Cancel) { return; } // If the event is not canceled, update the value. Orientation old = _orientation; if (_orientation != value) { _orientation = value; if (_owner is { }) { _owner.Orientation = value; } } // Best practice is to invoke the virtual method first. _owner?.OnOrientationChanged (_orientation); // Even though Changed is not cancelable, it is still a good practice to raise the event after. OrientationChanged?.Invoke (_owner, new (in _orientation)); } } /// /// Raised when the orientation is changing. This is cancelable. /// /// /// /// Views that implement should raise /// after the orientation has changed /// (_orientationHelper.OrientationChanging += (sender, e) => OrientationChanging?.Invoke (this, e);). /// /// /// This event will be raised after the method is called (assuming /// it was not canceled). /// /// public event EventHandler>? OrientationChanging; /// /// Raised when the orientation has changed. /// /// /// /// Views that implement should raise /// after the orientation has changed /// (_orientationHelper.OrientationChanged += (sender, e) => OrientationChanged?.Invoke (this, e);). /// /// /// This event will be raised after the method is called. /// /// public event EventHandler>? OrientationChanged; }