using System; using System.ComponentModel; using System.Runtime.CompilerServices; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.Input; using Avalonia.Input.Platform; using Avalonia.Interactivity; using Avalonia.Media; using Avalonia.Rendering; using Avalonia.Styling; using Avalonia.VisualTree; namespace Avalonia.Controls { /// /// Base class for Avalonia controls. /// /// /// The control class extends and adds the following features: /// /// - A property to allow user-defined data to be attached to the control. /// - and other context menu related members. /// public class Control : InputElement, IControl, INamed, IVisualBrushInitialize, ISetterValue { /// /// Defines the property. /// public static readonly StyledProperty?> FocusAdornerProperty = AvaloniaProperty.Register?>(nameof(FocusAdorner)); /// /// Defines the property. /// public static readonly StyledProperty TagProperty = AvaloniaProperty.Register(nameof(Tag)); /// /// Defines the property. /// public static readonly StyledProperty ContextMenuProperty = AvaloniaProperty.Register(nameof(ContextMenu)); /// /// Defines the property /// public static readonly StyledProperty ContextFlyoutProperty = AvaloniaProperty.Register(nameof(ContextFlyout)); /// /// Event raised when an element wishes to be scrolled into view. /// public static readonly RoutedEvent RequestBringIntoViewEvent = RoutedEvent.Register("RequestBringIntoView", RoutingStrategies.Bubble); /// /// Provides event data for the event. /// public static readonly RoutedEvent ContextRequestedEvent = RoutedEvent.Register(nameof(ContextRequested), RoutingStrategies.Tunnel | RoutingStrategies.Bubble); /// /// Defines the property. /// public static readonly AttachedProperty FlowDirectionProperty = AvaloniaProperty.RegisterAttached(nameof(FlowDirection), inherits: true); private DataTemplates? _dataTemplates; private IControl? _focusAdorner; /// /// Gets or sets the control's focus adorner. /// public ITemplate? FocusAdorner { get => GetValue(FocusAdornerProperty); set => SetValue(FocusAdornerProperty, value); } /// /// Gets or sets the data templates for the control. /// /// /// Each control may define data templates which are applied to the control itself and its /// children. /// public DataTemplates DataTemplates => _dataTemplates ??= new DataTemplates(); /// /// Gets or sets a context menu to the control. /// public ContextMenu? ContextMenu { get => GetValue(ContextMenuProperty); set => SetValue(ContextMenuProperty, value); } /// /// Gets or sets a context flyout to the control /// public FlyoutBase? ContextFlyout { get => GetValue(ContextFlyoutProperty); set => SetValue(ContextFlyoutProperty, value); } /// /// Gets or sets a user-defined object attached to the control. /// public object? Tag { get => GetValue(TagProperty); set => SetValue(TagProperty, value); } /// /// Gets or sets the text flow direction. /// public FlowDirection FlowDirection { get => GetValue(FlowDirectionProperty); set => SetValue(FlowDirectionProperty, value); } /// /// Occurs when the user has completed a context input gesture, such as a right-click. /// public event EventHandler? ContextRequested { add => AddHandler(ContextRequestedEvent, value); remove => RemoveHandler(ContextRequestedEvent, value); } public new IControl? Parent => (IControl?)base.Parent; /// bool IDataTemplateHost.IsDataTemplatesInitialized => _dataTemplates != null; /// void ISetterValue.Initialize(ISetter setter) { if (setter is Setter s && s.Property == ContextFlyoutProperty) { return; // Allow ContextFlyout to not need wrapping in