Browse Source

Use ItemCount to determine PseudoClass in ItemsControl

Murdo R Ergeaux 4 years ago
parent
commit
dbab1666a2

+ 9 - 6
src/Avalonia.Controls/ItemsControl.cs

@@ -346,6 +346,8 @@ namespace Avalonia.Controls
                 Presenter.Items = newValue;
             }
 
+            UpdatePseudoClasses();
+
             SubscribeToItems(newValue);
         }
 
@@ -372,9 +374,7 @@ namespace Avalonia.Controls
 
             Presenter?.ItemsChanged(e);
 
-            var collection = sender as ICollection;
-            PseudoClasses.Set(":empty", collection == null || collection.Count == 0);
-            PseudoClasses.Set(":singleitem", collection != null && collection.Count == 1);
+            UpdatePseudoClasses();
         }
 
         /// <summary>
@@ -431,9 +431,6 @@ namespace Avalonia.Controls
         /// <param name="items">The items collection.</param>
         private void SubscribeToItems(IEnumerable items)
         {
-            PseudoClasses.Set(":empty", items == null || items.Count() == 0);
-            PseudoClasses.Set(":singleitem", items != null && items.Count() == 1);
-
             if (items is INotifyCollectionChanged incc)
             {
                 CollectionChangedEventManager.Instance.AddListener(incc, this);
@@ -469,6 +466,12 @@ namespace Avalonia.Controls
             }
         }
 
+        private void UpdatePseudoClasses()
+        {
+            PseudoClasses.Set(":empty", ItemCount == 0);
+            PseudoClasses.Set(":singleitem", ItemCount == 1);
+        }
+
         protected static IInputElement GetNextControl(
             INavigableContainer container,
             NavigationDirection direction,

+ 64 - 0
tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs

@@ -393,6 +393,70 @@ namespace Avalonia.Controls.UnitTests
             Assert.Contains(":empty", target.Classes);
         }
 
+        [Fact]
+        public void Item_Count_Should_Be_Set_When_Items_Added()
+        {
+            var target = new ItemsControl()
+            {
+                Template = GetTemplate(),
+                Items = new[] { 1, 2, 3 },
+            };
+
+            Assert.Equal(3, target.ItemCount);
+        }
+
+        [Fact]
+        public void Item_Count_Should_Be_Set_When_Items_Changed()
+        {
+            var items = new ObservableCollection<int>() { 1, 2, 3 };
+
+            var target = new ItemsControl()
+            {
+                Template = GetTemplate(),
+                Items = items,
+            };
+
+            items.Add(4);
+
+            Assert.Equal(4, target.ItemCount);
+
+            items.Clear();
+
+            Assert.Equal(0, target.ItemCount);
+        }
+
+        [Fact]
+        public void Empty_Class_Should_Be_Set_When_Items_Collection_Cleared()
+        {
+            var items = new ObservableCollection<int>() { 1, 2, 3 };
+
+            var target = new ItemsControl()
+            {
+                Template = GetTemplate(),
+                Items = items,
+            };
+
+            items.Clear();
+
+            Assert.Contains(":empty", target.Classes);
+        }
+
+        [Fact]
+        public void Empty_Class_Should_Not_Be_Set_When_Items_Collection_Count_Increases()
+        {
+            var items = new ObservableCollection<int>() {};
+
+            var target = new ItemsControl()
+            {
+                Template = GetTemplate(),
+                Items = items,
+            };
+
+            items.Add(1);
+
+            Assert.DoesNotContain(":empty", target.Classes);
+        }
+
         [Fact]
         public void Setting_Presenter_Explicitly_Should_Set_Item_Parent()
         {