From f289099aebd9fde11ecfe92df35a4303566ba85e Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Fri, 20 Jan 2023 16:55:07 +0100 Subject: [PATCH] Added IChildIndexProvider.TotalCountChanged. --- .../LogicalTree/IChildIndexProvider.cs | 7 ++++++- .../Styling/Activators/NthChildActivator.cs | 19 +++++++++++++++++-- src/Avalonia.Controls/ItemsControl.cs | 8 ++++++++ src/Avalonia.Controls/Panel.cs | 15 +++++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/Avalonia.Base/LogicalTree/IChildIndexProvider.cs b/src/Avalonia.Base/LogicalTree/IChildIndexProvider.cs index 7fcd73273c..a5e191d63e 100644 --- a/src/Avalonia.Base/LogicalTree/IChildIndexProvider.cs +++ b/src/Avalonia.Base/LogicalTree/IChildIndexProvider.cs @@ -25,8 +25,13 @@ namespace Avalonia.LogicalTree bool TryGetTotalCount(out int count); /// - /// Notifies subscriber when child's index or total count was changed. + /// Notifies subscriber when a child's index was changed. /// event EventHandler? ChildIndexChanged; + + /// + /// Notifies subscriber when the total child count changes. + /// + event EventHandler? TotalCountChanged; } } diff --git a/src/Avalonia.Base/Styling/Activators/NthChildActivator.cs b/src/Avalonia.Base/Styling/Activators/NthChildActivator.cs index 64aad9aa6b..6c18081287 100644 --- a/src/Avalonia.Base/Styling/Activators/NthChildActivator.cs +++ b/src/Avalonia.Base/Styling/Activators/NthChildActivator.cs @@ -1,4 +1,5 @@ #nullable enable +using System; using Avalonia.LogicalTree; namespace Avalonia.Styling.Activators @@ -33,8 +34,16 @@ namespace Avalonia.Styling.Activators return NthChildSelector.Evaluate(index, _provider, _step, _offset, _reversed).IsMatch; } - protected override void Initialize() => _provider.ChildIndexChanged += ChildIndexChanged; - protected override void Deinitialize() => _provider.ChildIndexChanged -= ChildIndexChanged; + protected override void Initialize() + { + _provider.ChildIndexChanged += ChildIndexChanged; + _provider.TotalCountChanged += TotalCountChanged; + } + + protected override void Deinitialize() + { + _provider.ChildIndexChanged -= ChildIndexChanged; + } private void ChildIndexChanged(object? sender, ChildIndexChangedEventArgs e) { @@ -47,5 +56,11 @@ namespace Avalonia.Styling.Activators ReevaluateIsActive(); } } + + private void TotalCountChanged(object? sender, EventArgs e) + { + if (_reversed) + ReevaluateIsActive(); + } } } diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index 88991eec25..6e89a4eb1d 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -88,6 +88,7 @@ namespace Avalonia.Controls private int _itemCount; private ItemContainerGenerator? _itemContainerGenerator; private EventHandler? _childIndexChanged; + private EventHandler? _totalCountChanged; private IDataTemplate? _displayMemberItemTemplate; private Tuple? _containerBeingPrepared; private ScrollViewer? _scrollViewer; @@ -203,6 +204,12 @@ namespace Avalonia.Controls remove => _childIndexChanged -= value; } + event EventHandler? IChildIndexProvider.TotalCountChanged + { + add => _totalCountChanged += value; + remove => _totalCountChanged -= value; + } + /// /// Returns the container for the item at the specified index. /// @@ -418,6 +425,7 @@ namespace Avalonia.Controls else if (change.Property == ItemCountProperty) { UpdatePseudoClasses(change.GetNewValue()); + _totalCountChanged?.Invoke(this, EventArgs.Empty); } else if (change.Property == ItemContainerThemeProperty && _itemContainerGenerator is not null) { diff --git a/src/Avalonia.Controls/Panel.cs b/src/Avalonia.Controls/Panel.cs index 007d18c813..ee18b3c4ab 100644 --- a/src/Avalonia.Controls/Panel.cs +++ b/src/Avalonia.Controls/Panel.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; +using System.ComponentModel; using System.Linq; using Avalonia.LogicalTree; using Avalonia.Media; @@ -34,6 +35,7 @@ namespace Avalonia.Controls } private EventHandler? _childIndexChanged; + private EventHandler? _totalCountChanged; /// /// Initializes a new instance of the class. @@ -41,6 +43,7 @@ namespace Avalonia.Controls public Panel() { Children.CollectionChanged += ChildrenChanged; + Children.PropertyChanged += ChildrenPropertyChanged; } /// @@ -64,6 +67,12 @@ namespace Avalonia.Controls remove => _childIndexChanged -= value; } + event EventHandler? IChildIndexProvider.TotalCountChanged + { + add => _totalCountChanged += value; + remove => _totalCountChanged -= value; + } + /// /// Renders the visual to a . /// @@ -161,6 +170,12 @@ namespace Avalonia.Controls InvalidateMeasure(); } + private void ChildrenPropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(Children.Count) || e.PropertyName is null) + _totalCountChanged?.Invoke(this, EventArgs.Empty); + } + private static void AffectsParentArrangeInvalidate(AvaloniaPropertyChangedEventArgs e) where TPanel : Panel {