diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index a2fb21330c..b6d74da06e 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -84,6 +84,7 @@ namespace Avalonia.Controls private ItemContainerGenerator? _itemContainerGenerator; private EventHandler? _childIndexChanged; private IDataTemplate? _displayMemberItemTemplate; + private Tuple? _containerBeingPrepared; /// /// Initializes static members of the class. @@ -221,19 +222,8 @@ namespace Avalonia.Controls /// void IItemsPresenterHost.RegisterItemsPresenter(ItemsPresenter presenter) { - if (Presenter is IChildIndexProvider oldInnerProvider) - { - oldInnerProvider.ChildIndexChanged -= PresenterChildIndexChanged; - } - Presenter = presenter; - ////ItemContainerGenerator?.Clear(); - - if (Presenter is IChildIndexProvider innerProvider) - { - innerProvider.ChildIndexChanged += PresenterChildIndexChanged; - _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.Empty); - } + _childIndexChanged?.Invoke(this, ChildIndexChangedEventArgs.Empty); } void ICollectionChangedListener.PreChanged(INotifyCollectionChanged sender, NotifyCollectionChangedEventArgs e) @@ -513,11 +503,16 @@ namespace Avalonia.Controls container.DataContext = item; PrepareContainerForItemOverride(container, item, index); + + _containerBeingPrepared = new(index, container); + _childIndexChanged?.Invoke(this, new ChildIndexChangedEventArgs(container)); + _containerBeingPrepared = null; } internal void ItemContainerIndexChanged(Control container, int oldIndex, int newIndex) { ContainerIndexChangedOverride(container, oldIndex, newIndex); + _childIndexChanged?.Invoke(this, new ChildIndexChangedEventArgs(container)); } /// @@ -681,27 +676,17 @@ namespace Avalonia.Controls } } - private void PresenterChildIndexChanged(object? sender, ChildIndexChangedEventArgs e) - { - _childIndexChanged?.Invoke(this, e); - } - int IChildIndexProvider.GetChildIndex(ILogical child) { - return Presenter is IChildIndexProvider innerProvider - ? innerProvider.GetChildIndex(child) : -1; + if (_containerBeingPrepared?.Item2 == child) + return _containerBeingPrepared.Item1; + + return child is Control container ? IndexFromContainer(container) : -1; } bool IChildIndexProvider.TryGetTotalCount(out int count) { - if (Presenter is IChildIndexProvider presenter - && presenter.TryGetTotalCount(out count)) - { - return true; - } - - count = ItemCount; - return true; + return Items.TryGetCountFast(out count); } } } diff --git a/src/Avalonia.Controls/VirtualizingStackPanel.cs b/src/Avalonia.Controls/VirtualizingStackPanel.cs index 115aff64c8..f211ec2edb 100644 --- a/src/Avalonia.Controls/VirtualizingStackPanel.cs +++ b/src/Avalonia.Controls/VirtualizingStackPanel.cs @@ -830,7 +830,7 @@ namespace Avalonia.Controls for (var i = start; i < end; ++i) { if (_elements[i] is Control element) - updateElementIndex(element, newIndex - count, newIndex); + updateElementIndex(element, newIndex + count, newIndex); ++newIndex; } } diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs index 6361dcdbea..70cf3c8276 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs @@ -349,7 +349,6 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml } } - [Fact] public void Style_Can_Use_NthChild_Selector_With_ListBox() { @@ -376,16 +375,18 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml window.Show(); - IEnumerable GetColors() => list.Presenter.Panel.Children.Cast().Select(t => t.Background); + IEnumerable GetColors() => list.GetRealizedContainers().Cast().Select(t => t.Background); Assert.Equal(new[] { Brushes.Transparent, Brushes.Green, Brushes.Transparent }, GetColors()); collection.Remove(Brushes.Green); + window.LayoutManager.ExecuteLayoutPass(); Assert.Equal(new[] { Brushes.Transparent, Brushes.Blue }, GetColors()); collection.Add(Brushes.Violet); collection.Add(Brushes.Black); + window.LayoutManager.ExecuteLayoutPass(); Assert.Equal(new[] { Brushes.Transparent, Brushes.Blue, Brushes.Transparent, Brushes.Black }, GetColors()); }