From f276c4ed8b992017003d94a863128effdd068fe2 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Thu, 21 Oct 2021 18:50:02 -0400 Subject: [PATCH] Changes after review --- samples/ControlCatalog/Pages/ListBoxPage.xaml | 2 +- src/Avalonia.Controls/ItemsControl.cs | 15 ++++++++++++--- src/Avalonia.Controls/Panel.cs | 10 ++++++---- .../Presenters/ItemsPresenterBase.cs | 8 +++++--- src/Avalonia.Controls/Repeater/ItemsRepeater.cs | 10 ++++++---- .../LogicalTree/IChildIndexProvider.cs | 4 ++-- .../Styling/Activators/NthChildActivator.cs | 9 ++------- src/Avalonia.Styling/Styling/NthChildSelector.cs | 9 ++++++--- .../Xaml/StyleTests.cs | 2 -- .../SelectorTests_NthChild.cs | 2 -- .../SelectorTests_NthLastChild.cs | 1 - 11 files changed, 40 insertions(+), 32 deletions(-) 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;