using System; using System.Diagnostics; using System.Globalization; using Avalonia.Controls; namespace Avalonia.Xaml.Interactivity; /// /// A base class for behaviors, implementing the basic plumbing of . /// public abstract class Behavior : AvaloniaObject, IBehavior, IBehaviorEventsHandler { /// /// Identifies the avalonia property. /// public static readonly StyledProperty IsEnabledProperty = AvaloniaProperty.Register(nameof(IsEnabled), defaultValue: true); /// /// Gets the to which the behavior is attached. /// public AvaloniaObject? AssociatedObject { get; private set; } /// /// Gets or sets a value indicating whether this instance is enabled. /// /// true if this instance is enabled; otherwise, false. public bool IsEnabled { get => GetValue(IsEnabledProperty); set => SetValue(IsEnabledProperty, value); } /// /// Attaches the behavior to the specified . /// /// The to which to attach. /// is null. public void Attach(AvaloniaObject? associatedObject) { if (Equals(associatedObject, AssociatedObject)) { return; } if (AssociatedObject is not null) { throw new InvalidOperationException(string.Format( CultureInfo.CurrentCulture, "An instance of a behavior cannot be attached to more than one object at a time.")); } Debug.Assert(associatedObject is not null, "Cannot attach the behavior to a null object."); AssociatedObject = associatedObject ?? throw new ArgumentNullException(nameof(associatedObject)); OnAttached(); } /// /// Detaches the behaviors from the . /// public void Detach() { OnDetaching(); AssociatedObject = null; } /// /// Called after the behavior is attached to the . /// /// /// Override this to hook up functionality to the /// protected virtual void OnAttached() { } /// /// Called when the behavior is being detached from its . /// /// /// Override this to unhook functionality from the /// protected virtual void OnDetaching() { } void IBehaviorEventsHandler.AttachedToVisualTreeEventHandler() => OnAttachedToVisualTree(); void IBehaviorEventsHandler.DetachedFromVisualTreeEventHandler() => OnDetachedFromVisualTree(); void IBehaviorEventsHandler.AttachedToLogicalTreeEventHandler() => OnAttachedToLogicalTree(); void IBehaviorEventsHandler.DetachedFromLogicalTreeEventHandler() => OnDetachedFromLogicalTree(); void IBehaviorEventsHandler.LoadedEventHandler() => OnLoaded(); void IBehaviorEventsHandler.UnloadedEventHandler() => OnUnloaded(); /// /// Called after the is attached to the visual tree. /// /// /// Invoked only when the is of type . /// protected virtual void OnAttachedToVisualTree() { } /// /// Called when the is being detached from the visual tree. /// /// /// Invoked only when the is of type . /// protected virtual void OnDetachedFromVisualTree() { } /// /// Called after the is attached to the logical tree. /// /// /// Invoked only when the is of type . /// protected virtual void OnAttachedToLogicalTree() { } /// /// Called when the is being detached from the logical tree. /// /// /// Invoked only when the is of type . /// protected virtual void OnDetachedFromLogicalTree() { } /// /// Called after the is loaded. /// /// /// Invoked only when the is of type . /// protected virtual void OnLoaded() { } /// /// Called when the is unloaded. /// /// /// Invoked only when the is of type . /// protected virtual void OnUnloaded() { } }