using System; using System.Linq; using Avalonia.Data; using Avalonia.LogicalTree; using Avalonia.Styling; namespace Avalonia.Controls { /// /// Adds common functionality to . /// public static class ControlExtensions { /// /// Tries to bring the control into view. /// /// The control. public static void BringIntoView(this IControl control) { Contract.Requires(control != null); control.BringIntoView(new Rect(control.Bounds.Size)); } /// /// Tries to bring the control into view. /// /// The control. /// The area of the control to being into view. public static void BringIntoView(this IControl control, Rect rect) { Contract.Requires(control != null); if (control.IsEffectivelyVisible) { var ev = new RequestBringIntoViewEventArgs { RoutedEvent = Control.RequestBringIntoViewEvent, TargetObject = control, TargetRect = rect, }; control.RaiseEvent(ev); } } /// /// Finds the named control in the scope of the specified control. /// /// The type of the control to find. /// The control to look in. /// The name of the control to find. /// The control or null if not found. public static T FindControl(this IControl control, string name) where T : class, IControl { Contract.Requires(control != null); Contract.Requires(name != null); var nameScope = control.FindNameScope(); if (nameScope == null) { throw new InvalidOperationException("Could not find parent name scope."); } return nameScope.Find(name); } /// /// Finds the named control in the scope of the specified control and throws if not found. /// /// The type of the control to find. /// The control to look in. /// The name of the control to find. /// The control. public static T GetControl(this IControl control, string name) where T : class, IControl { _ = control ?? throw new ArgumentNullException(nameof(control)); _ = name ?? throw new ArgumentNullException(nameof(name)); var nameScope = control.FindNameScope(); if (nameScope == null) { throw new InvalidOperationException("Could not find parent name scope."); } return nameScope.Find(name) ?? throw new ArgumentException($"Could not find control named '{name}'."); } /// /// Sets a pseudoclass depending on an observable trigger. /// /// The pseudoclasses collection. /// The name of the pseudoclass to set. /// The trigger: true adds the pseudoclass, false removes. /// A disposable used to cancel the subscription. public static IDisposable Set(this IPseudoClasses classes, string name, IObservable trigger) { Contract.Requires(classes != null); return trigger.Subscribe(x => classes.Set(name, x)); } } }