diff --git a/samples/ControlCatalog/Pages/ListBoxPage.xaml b/samples/ControlCatalog/Pages/ListBoxPage.xaml
index cb29f54c94..b36629fb2a 100644
--- a/samples/ControlCatalog/Pages/ListBoxPage.xaml
+++ b/samples/ControlCatalog/Pages/ListBoxPage.xaml
@@ -15,7 +15,7 @@
ListBox
Hosts a collection of ListBoxItem.
- Each 2nd item is highlighted
+ Each 5th item is highlighted with nth-child(5n+3) and nth-last-child(5n+4) rules.
Multiple
diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs
index 7b28335a6d..1ff49326b6 100644
--- a/src/Avalonia.Controls/ItemsControl.cs
+++ b/src/Avalonia.Controls/ItemsControl.cs
@@ -13,7 +13,6 @@ using Avalonia.Controls.Utils;
using Avalonia.Input;
using Avalonia.LogicalTree;
using Avalonia.Metadata;
-using Avalonia.Styling;
using Avalonia.VisualTree;
namespace Avalonia.Controls
@@ -147,8 +146,6 @@ namespace Avalonia.Controls
protected set;
}
- int? IChildIndexProvider.TotalCount => (Presenter as IChildIndexProvider)?.TotalCount ?? ItemCount;
-
event EventHandler IChildIndexProvider.ChildIndexChanged
{
add => _childIndexChanged += value;
@@ -538,5 +535,17 @@ namespace Avalonia.Controls
return Presenter is IChildIndexProvider innerProvider
? innerProvider.GetChildIndex(child) : -1;
}
+
+ bool IChildIndexProvider.TryGetTotalCount(out int count)
+ {
+ if (Presenter is IChildIndexProvider presenter
+ && presenter.TryGetTotalCount(out count))
+ {
+ return true;
+ }
+
+ count = ItemCount;
+ return true;
+ }
}
}
diff --git a/src/Avalonia.Controls/Panel.cs b/src/Avalonia.Controls/Panel.cs
index 9c93126506..b182f9d261 100644
--- a/src/Avalonia.Controls/Panel.cs
+++ b/src/Avalonia.Controls/Panel.cs
@@ -2,8 +2,6 @@ using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
-
-using Avalonia.Controls.Presenters;
using Avalonia.LogicalTree;
using Avalonia.Media;
using Avalonia.Metadata;
@@ -59,8 +57,6 @@ namespace Avalonia.Controls
set { SetValue(BackgroundProperty, value); }
}
- int? IChildIndexProvider.TotalCount => Children.Count;
-
event EventHandler IChildIndexProvider.ChildIndexChanged
{
add => _childIndexChanged += value;
@@ -180,5 +176,11 @@ namespace Avalonia.Controls
{
return child is IControl control ? Children.IndexOf(control) : -1;
}
+
+ public bool TryGetTotalCount(out int count)
+ {
+ count = Children.Count;
+ return true;
+ }
}
}
diff --git a/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs b/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs
index b92af1eb9c..aeead7bfd0 100644
--- a/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs
+++ b/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections;
using System.Collections.Specialized;
-
using Avalonia.Collections;
using Avalonia.Controls.Generators;
using Avalonia.Controls.Templates;
@@ -132,8 +131,6 @@ namespace Avalonia.Controls.Presenters
protected bool IsHosted => TemplatedParent is IItemsPresenterHost;
- int? IChildIndexProvider.TotalCount => Items.TryGetCountFast(out var count) ? count : (int?)null;
-
event EventHandler IChildIndexProvider.ChildIndexChanged
{
add => _childIndexChanged += value;
@@ -285,5 +282,10 @@ namespace Avalonia.Controls.Presenters
return -1;
}
+
+ bool IChildIndexProvider.TryGetTotalCount(out int count)
+ {
+ return Items.TryGetCountFast(out count);
+ }
}
}
diff --git a/src/Avalonia.Controls/Repeater/ItemsRepeater.cs b/src/Avalonia.Controls/Repeater/ItemsRepeater.cs
index 6d89a70670..ecc0fa3a48 100644
--- a/src/Avalonia.Controls/Repeater/ItemsRepeater.cs
+++ b/src/Avalonia.Controls/Repeater/ItemsRepeater.cs
@@ -6,13 +6,11 @@
using System;
using System.Collections;
using System.Collections.Specialized;
-
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.Layout;
using Avalonia.Logging;
using Avalonia.LogicalTree;
-using Avalonia.Styling;
using Avalonia.Utilities;
using Avalonia.VisualTree;
@@ -167,8 +165,6 @@ namespace Avalonia.Controls
}
}
- int? IChildIndexProvider.TotalCount => ItemsSourceView.Count;
-
event EventHandler IChildIndexProvider.ChildIndexChanged
{
add => _childIndexChanged += value;
@@ -182,6 +178,12 @@ namespace Avalonia.Controls
: -1;
}
+ bool IChildIndexProvider.TryGetTotalCount(out int count)
+ {
+ count = ItemsSourceView.Count;
+ return true;
+ }
+
///
/// Occurs each time an element is cleared and made available to be re-used.
///
diff --git a/src/Avalonia.Styling/LogicalTree/IChildIndexProvider.cs b/src/Avalonia.Styling/LogicalTree/IChildIndexProvider.cs
index 53e2199d28..7fcd73273c 100644
--- a/src/Avalonia.Styling/LogicalTree/IChildIndexProvider.cs
+++ b/src/Avalonia.Styling/LogicalTree/IChildIndexProvider.cs
@@ -20,9 +20,9 @@ namespace Avalonia.LogicalTree
///
/// Total children count or null if source is infinite.
- /// Some Avalonia features might not work if is null, for instance: nth-last-child selector.
+ /// Some Avalonia features might not work if returns false, for instance: nth-last-child selector.
///
- int? TotalCount { get; }
+ bool TryGetTotalCount(out int count);
///
/// Notifies subscriber when child's index or total count was changed.
diff --git a/src/Avalonia.Styling/Styling/Activators/NthChildActivator.cs b/src/Avalonia.Styling/Styling/Activators/NthChildActivator.cs
index 5d23d1ffd1..803809a8ce 100644
--- a/src/Avalonia.Styling/Styling/Activators/NthChildActivator.cs
+++ b/src/Avalonia.Styling/Styling/Activators/NthChildActivator.cs
@@ -1,6 +1,4 @@
#nullable enable
-using System;
-
using Avalonia.LogicalTree;
namespace Avalonia.Styling.Activators
@@ -15,7 +13,6 @@ namespace Avalonia.Styling.Activators
private readonly int _step;
private readonly int _offset;
private readonly bool _reversed;
- private EventHandler? _childIndexChangedHandler;
public NthChildActivator(
ILogical control,
@@ -29,17 +26,15 @@ namespace Avalonia.Styling.Activators
_reversed = reversed;
}
- private EventHandler ChildIndexChangedHandler => _childIndexChangedHandler ??= ChildIndexChanged;
-
protected override void Initialize()
{
PublishNext(IsMatching());
- _provider.ChildIndexChanged += ChildIndexChangedHandler;
+ _provider.ChildIndexChanged += ChildIndexChanged;
}
protected override void Deinitialize()
{
- _provider.ChildIndexChanged -= ChildIndexChangedHandler;
+ _provider.ChildIndexChanged -= ChildIndexChanged;
}
private void ChildIndexChanged(object sender, ChildIndexChangedEventArgs e)
diff --git a/src/Avalonia.Styling/Styling/NthChildSelector.cs b/src/Avalonia.Styling/Styling/NthChildSelector.cs
index e844fb51f8..aff34ea17c 100644
--- a/src/Avalonia.Styling/Styling/NthChildSelector.cs
+++ b/src/Avalonia.Styling/Styling/NthChildSelector.cs
@@ -1,7 +1,6 @@
#nullable enable
using System;
using System.Text;
-
using Avalonia.LogicalTree;
using Avalonia.Styling.Activators;
@@ -51,7 +50,11 @@ namespace Avalonia.Styling
protected override SelectorMatch Evaluate(IStyleable control, bool subscribe)
{
- var logical = (ILogical)control;
+ if (!(control is ILogical logical))
+ {
+ return SelectorMatch.NeverThisType;
+ }
+
var controlParent = logical.LogicalParent;
if (controlParent is IChildIndexProvider childIndexProvider)
@@ -78,7 +81,7 @@ namespace Avalonia.Styling
if (reversed)
{
- if (childIndexProvider.TotalCount is int totalCountValue)
+ if (childIndexProvider.TryGetTotalCount(out var totalCountValue))
{
index = totalCountValue - index;
}
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs
index 28960c8bf6..022ff0c3a4 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs
@@ -1,10 +1,8 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
-using System.Threading.Tasks;
using System.Xml;
using Avalonia.Controls;
-using Avalonia.Markup.Data;
using Avalonia.Markup.Xaml.Styling;
using Avalonia.Markup.Xaml.Templates;
using Avalonia.Media;
diff --git a/tests/Avalonia.Styling.UnitTests/SelectorTests_NthChild.cs b/tests/Avalonia.Styling.UnitTests/SelectorTests_NthChild.cs
index 8a8e46fc4b..1d101b8ea0 100644
--- a/tests/Avalonia.Styling.UnitTests/SelectorTests_NthChild.cs
+++ b/tests/Avalonia.Styling.UnitTests/SelectorTests_NthChild.cs
@@ -1,7 +1,5 @@
using System.Threading.Tasks;
-
using Avalonia.Controls;
-
using Xunit;
namespace Avalonia.Styling.UnitTests
diff --git a/tests/Avalonia.Styling.UnitTests/SelectorTests_NthLastChild.cs b/tests/Avalonia.Styling.UnitTests/SelectorTests_NthLastChild.cs
index 8d9d490724..00a99523c7 100644
--- a/tests/Avalonia.Styling.UnitTests/SelectorTests_NthLastChild.cs
+++ b/tests/Avalonia.Styling.UnitTests/SelectorTests_NthLastChild.cs
@@ -1,5 +1,4 @@
using System.Threading.Tasks;
-
using Avalonia.Controls;
using Xunit;