diff --git a/src/Avalonia.Base/LogicalTree/ChildIndexChangedEventArgs.cs b/src/Avalonia.Base/LogicalTree/ChildIndexChangedEventArgs.cs
index 8f2be75e0f..6b41c1c66c 100644
--- a/src/Avalonia.Base/LogicalTree/ChildIndexChangedEventArgs.cs
+++ b/src/Avalonia.Base/LogicalTree/ChildIndexChangedEventArgs.cs
@@ -1,26 +1,59 @@
-#nullable enable
-using System;
+using System;
+
+#nullable enable
namespace Avalonia.LogicalTree
{
///
- /// Event args for event.
+ /// Describes the action that caused a event.
///
- public class ChildIndexChangedEventArgs : EventArgs
+ public enum ChildIndexChangedAction
{
- public static new ChildIndexChangedEventArgs Empty { get; } = new ChildIndexChangedEventArgs();
+ ///
+ /// The index of a single child changed.
+ ///
+ ChildIndexChanged,
- private ChildIndexChangedEventArgs()
- {
- Index = -1;
- }
+ ///
+ /// The index of multiple children changed and all children should be re-evaluated.
+ ///
+ ChildIndexesReset,
+
+ ///
+ /// The total number of children changed.
+ ///
+ TotalCountChanged,
+ }
+ ///
+ /// Event args for event.
+ ///
+ public class ChildIndexChangedEventArgs : EventArgs
+ {
+ ///
+ /// Initializes a new instance of the class with
+ /// an action of .
+ ///
+ /// The child whose index was changed.
+ /// The new index of the child.
public ChildIndexChangedEventArgs(ILogical child, int index)
{
+ Action = ChildIndexChangedAction.ChildIndexChanged;
Child = child;
Index = index;
}
+ private ChildIndexChangedEventArgs(ChildIndexChangedAction action)
+ {
+ Action = action;
+ Index = -1;
+ }
+
+ ///
+ /// Gets the type of change action that ocurred on the list control.
+ ///
+ public ChildIndexChangedAction Action { get; }
+
///
/// Gets the logical child whose index was changed or null if all children should be re-evaluated.
///
@@ -30,5 +63,17 @@ namespace Avalonia.LogicalTree
/// Gets the new index of or -1 if all children should be re-evaluated.
///
public int Index { get; }
+
+ ///
+ /// Gets an instance of the with an action of
+ /// .
+ ///
+ public static ChildIndexChangedEventArgs ChildIndexesReset { get; } = new(ChildIndexChangedAction.ChildIndexesReset);
+
+ ///
+ /// Gets an instance of the with an action of
+ /// .
+ ///
+ public static ChildIndexChangedEventArgs TotalCountChanged { get; } = new(ChildIndexChangedAction.TotalCountChanged);
}
}
diff --git a/src/Avalonia.Base/LogicalTree/IChildIndexProvider.cs b/src/Avalonia.Base/LogicalTree/IChildIndexProvider.cs
index a5e191d63e..186c9527f2 100644
--- a/src/Avalonia.Base/LogicalTree/IChildIndexProvider.cs
+++ b/src/Avalonia.Base/LogicalTree/IChildIndexProvider.cs
@@ -28,10 +28,5 @@ namespace Avalonia.LogicalTree
/// 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 e0fa056765..8bdcec2e53 100644
--- a/src/Avalonia.Base/Styling/Activators/NthChildActivator.cs
+++ b/src/Avalonia.Base/Styling/Activators/NthChildActivator.cs
@@ -37,7 +37,6 @@ namespace Avalonia.Styling.Activators
protected override void Initialize()
{
_provider.ChildIndexChanged += ChildIndexChanged;
- _provider.TotalCountChanged += TotalCountChanged;
}
protected override void Deinitialize()
@@ -48,9 +47,11 @@ namespace Avalonia.Styling.Activators
private void ChildIndexChanged(object? sender, ChildIndexChangedEventArgs e)
{
// Run matching again if:
- // 1. e.Child is null, when all children indices were changed.
- // 2. Subscribed child index was changed.
- if (e.Child is null || e.Child == _control)
+ // 1. Subscribed child index was changed
+ // 2. Child indexes were reset
+ // 3. We're a reversed (nth-last-child) selector and total count has changed
+ if ((e.Child == _control || e.Action == ChildIndexChangedAction.ChildIndexesReset) ||
+ (_reversed && e.Action == ChildIndexChangedAction.TotalCountChanged))
{
// We're using the _index field to pass the index of the child to EvaluateIsActive
// *only* when the active state is re-evaluated via this event handler. The docs
diff --git a/src/Avalonia.Controls.DataGrid/Primitives/DataGridCellsPresenter.cs b/src/Avalonia.Controls.DataGrid/Primitives/DataGridCellsPresenter.cs
index 06a77f0894..f5db7c0855 100644
--- a/src/Avalonia.Controls.DataGrid/Primitives/DataGridCellsPresenter.cs
+++ b/src/Avalonia.Controls.DataGrid/Primitives/DataGridCellsPresenter.cs
@@ -336,7 +336,7 @@ namespace Avalonia.Controls.Primitives
internal void InvalidateChildIndex()
{
- _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.Empty);
+ _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.ChildIndexesReset);
}
private bool ShouldDisplayCell(DataGridColumn column, double frozenLeftEdge, double scrollingLeftEdge)
diff --git a/src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs b/src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs
index f9b84793c6..fcf72385b2 100644
--- a/src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs
+++ b/src/Avalonia.Controls.DataGrid/Primitives/DataGridColumnHeadersPresenter.cs
@@ -423,7 +423,7 @@ namespace Avalonia.Controls.Primitives
internal void InvalidateChildIndex()
{
- _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.Empty);
+ _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.ChildIndexesReset);
}
}
}
diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs
index 8c3c65a6a7..9483f98881 100644
--- a/src/Avalonia.Controls/ItemsControl.cs
+++ b/src/Avalonia.Controls/ItemsControl.cs
@@ -101,7 +101,6 @@ namespace Avalonia.Controls
private int _itemCount;
private ItemContainerGenerator? _itemContainerGenerator;
private EventHandler? _childIndexChanged;
- private EventHandler? _totalCountChanged;
private IDataTemplate? _displayMemberItemTemplate;
private ScrollViewer? _scrollViewer;
private ItemsPresenter? _itemsPresenter;
@@ -218,12 +217,6 @@ namespace Avalonia.Controls
remove => _childIndexChanged -= value;
}
- event EventHandler? IChildIndexProvider.TotalCountChanged
- {
- add => _totalCountChanged += value;
- remove => _totalCountChanged -= value;
- }
-
///
public event EventHandler HorizontalSnapPointsChanged
{
@@ -500,7 +493,7 @@ namespace Avalonia.Controls
else if (change.Property == ItemCountProperty)
{
UpdatePseudoClasses(change.GetNewValue());
- _totalCountChanged?.Invoke(this, EventArgs.Empty);
+ _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.TotalCountChanged);
}
else if (change.Property == ItemContainerThemeProperty && _itemContainerGenerator is not null)
{
@@ -585,7 +578,7 @@ namespace Avalonia.Controls
internal void RegisterItemsPresenter(ItemsPresenter presenter)
{
Presenter = presenter;
- _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.Empty);
+ _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.ChildIndexesReset);
}
internal void PrepareItemContainer(Control container, object? item, int index)
diff --git a/src/Avalonia.Controls/Panel.cs b/src/Avalonia.Controls/Panel.cs
index 3006efb7de..10391afca2 100644
--- a/src/Avalonia.Controls/Panel.cs
+++ b/src/Avalonia.Controls/Panel.cs
@@ -35,7 +35,6 @@ namespace Avalonia.Controls
}
private EventHandler? _childIndexChanged;
- private EventHandler? _totalCountChanged;
///
/// Initializes a new instance of the class.
@@ -67,12 +66,6 @@ namespace Avalonia.Controls
remove => _childIndexChanged -= value;
}
- event EventHandler? IChildIndexProvider.TotalCountChanged
- {
- add => _totalCountChanged += value;
- remove => _totalCountChanged -= value;
- }
-
///
/// Renders the visual to a .
///
@@ -161,7 +154,7 @@ namespace Avalonia.Controls
throw new NotSupportedException();
}
- _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.Empty);
+ _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.ChildIndexesReset);
InvalidateMeasureOnChildrenChanged();
}
@@ -173,7 +166,7 @@ namespace Avalonia.Controls
private void ChildrenPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(Children.Count) || e.PropertyName is null)
- _totalCountChanged?.Invoke(this, EventArgs.Empty);
+ _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.TotalCountChanged);
}
private static void AffectsParentArrangeInvalidate(AvaloniaPropertyChangedEventArgs e)