diff --git a/src/Avalonia.Controls/Control.cs b/src/Avalonia.Controls/Control.cs index 524362fcf9..d0bf24947b 100644 --- a/src/Avalonia.Controls/Control.cs +++ b/src/Avalonia.Controls/Control.cs @@ -84,6 +84,13 @@ namespace Avalonia.Controls nameof(Unloaded), RoutingStrategies.Direct); + /// + /// Defines the event. + /// + public static readonly RoutedEvent SizeChangedEvent = + RoutedEvent.Register( + nameof(SizeChanged), RoutingStrategies.Bubble); + /// /// Defines the property. /// @@ -211,6 +218,15 @@ namespace Avalonia.Controls remove => RemoveHandler(UnloadedEvent, value); } + /// + /// Occurs when the bounds (actual size) of the control have changed. + /// + public event EventHandler? SizeChanged + { + add => AddHandler(SizeChangedEvent, value); + remove => RemoveHandler(SizeChangedEvent, value); + } + public new IControl? Parent => (IControl?)base.Parent; /// @@ -530,14 +546,28 @@ namespace Avalonia.Controls } } + /// protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { base.OnPropertyChanged(change); - if (change.Property == FlowDirectionProperty) + if (change.Property == BoundsProperty) + { + var oldValue = change.GetOldValue(); + var newValue = change.GetNewValue(); + + var sizeChangedEventArgs = new SizeChangedEventArgs( + SizeChangedEvent, + source: this, + newSize: new Size(newValue.Width, newValue.Height), + previousSize: new Size(oldValue.Width, oldValue.Height)); + + RaiseEvent(sizeChangedEventArgs); + } + else if (change.Property == FlowDirectionProperty) { InvalidateMirrorTransform(); - + foreach (var visual in VisualChildren) { if (visual is Control child) diff --git a/src/Avalonia.Controls/SizeChangedEventArgs.cs b/src/Avalonia.Controls/SizeChangedEventArgs.cs new file mode 100644 index 0000000000..d983e375c2 --- /dev/null +++ b/src/Avalonia.Controls/SizeChangedEventArgs.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Avalonia.Interactivity; + +namespace Avalonia.Controls +{ + /// + /// Provides data specific to a SizeChanged event. + /// + public class SizeChangedEventArgs : RoutedEventArgs + { + public SizeChangedEventArgs(RoutedEvent? routedEvent) + : base (routedEvent) + { + } + + public SizeChangedEventArgs(RoutedEvent? routedEvent, IInteractive? source) + : base(routedEvent, source) + { + } + + public SizeChangedEventArgs( + RoutedEvent? routedEvent, + IInteractive? source, + Size newSize, + Size previousSize) + : base(routedEvent, source) + { + NewSize = newSize; + PreviousSize = previousSize; + HeightChanged = newSize.Height != previousSize.Height; + WidthChanged = newSize.Width != previousSize.Width; + } + + /// + /// Gets a value indicating whether the height of the new size is different + /// than the previous size height. + /// + public bool HeightChanged { get; init; } + + /// + /// Gets the new size (or bounds) of the object. + /// + public Size NewSize { get; init; } + + /// + /// Gets the previous size (or bounds) of the object. + /// + public Size PreviousSize { get; init; } + + /// + /// Gets a value indicating whether the width of the new size is different + /// than the previous size width. + /// + public bool WidthChanged { get; init; } + } +}