From acb63e425b509e885fe11c52a3cc5cfe7f9fce1b Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sat, 2 May 2015 19:43:11 +0200 Subject: [PATCH] Fix ItemsControl :empty class. --- Perspex.Controls/ItemsControl.cs | 58 +++++++++++-------- .../ItemsControlTests.cs | 37 ++++++++++++ 2 files changed, 70 insertions(+), 25 deletions(-) diff --git a/Perspex.Controls/ItemsControl.cs b/Perspex.Controls/ItemsControl.cs index 312ed27b88..311804b1bb 100644 --- a/Perspex.Controls/ItemsControl.cs +++ b/Perspex.Controls/ItemsControl.cs @@ -6,17 +6,17 @@ namespace Perspex.Controls { - using System; - using System.Collections; - using System.ComponentModel; - using System.Diagnostics.CodeAnalysis; - using System.Linq; using Perspex.Collections; using Perspex.Controls.Generators; using Perspex.Controls.Presenters; using Perspex.Controls.Primitives; using Perspex.Controls.Templates; - using Perspex.VisualTree; + using Perspex.Controls.Utils; + using System; + using System.Collections; + using System.Collections.Specialized; + using System.Diagnostics.CodeAnalysis; + using System.Linq; public class ItemsControl : TemplatedControl, ILogical { @@ -35,9 +35,18 @@ namespace Perspex.Controls private PerspexReadOnlyListView logicalChildren = new PerspexReadOnlyListView(x => (ILogical)x); + static ItemsControl() + { + ItemsProperty.Changed.Subscribe(e => + { + var control = e.Sender as ItemsControl; + control?.ItemsChanged((IEnumerable)e.OldValue, (IEnumerable)e.NewValue); + }); + } + public ItemsControl() { - this.GetObservableWithHistory(ItemsProperty).Subscribe(this.ItemsChanged); + this.ItemsChanged(null, null); } public ItemContainerGenerator ItemContainerGenerator @@ -95,16 +104,16 @@ namespace Perspex.Controls } } - private void ItemsChanged(Tuple value) + protected virtual void ItemsChanged(IEnumerable oldValue, IEnumerable newValue) { - INotifyPropertyChanged inpc = value.Item1 as INotifyPropertyChanged; + var incc = oldValue as INotifyCollectionChanged; - if (inpc != null) + if (incc != null) { - inpc.PropertyChanged -= this.ItemsPropertyChanged; + incc.CollectionChanged += this.ItemsCollectionChanged; } - if (value.Item2 == null || !value.Item2.OfType().Any()) + if (newValue == null || newValue.Count() == 0) { this.Classes.Add(":empty"); } @@ -113,26 +122,25 @@ namespace Perspex.Controls this.Classes.Remove(":empty"); } - inpc = value.Item2 as INotifyPropertyChanged; + incc = newValue as INotifyCollectionChanged; - if (inpc != null) + if (incc != null) { - inpc.PropertyChanged += this.ItemsPropertyChanged; + incc.CollectionChanged -= this.ItemsCollectionChanged; } } - private void ItemsPropertyChanged(object sender, PropertyChangedEventArgs e) + protected virtual void ItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { - if (e.PropertyName == "Count") + var collection = sender as ICollection; + + if (collection.Count == 0) { - if (((IList)sender).Count == 0) - { - this.Classes.Add(":empty"); - } - else - { - this.Classes.Remove(":empty"); - } + this.Classes.Add(":empty"); + } + else + { + this.Classes.Remove(":empty"); } } } diff --git a/Tests/Perspex.Controls.UnitTests/ItemsControlTests.cs b/Tests/Perspex.Controls.UnitTests/ItemsControlTests.cs index ab21dcc766..872ee9a2a0 100644 --- a/Tests/Perspex.Controls.UnitTests/ItemsControlTests.cs +++ b/Tests/Perspex.Controls.UnitTests/ItemsControlTests.cs @@ -238,6 +238,43 @@ namespace Perspex.Controls.UnitTests Assert.Same(before, after); } + [Fact] + public void Empty_Class_Should_Initially_Be_Applied() + { + var target = new ItemsControl() + { + Template = this.GetTemplate(), + }; + + Assert.True(target.Classes.Contains(":empty")); + } + + [Fact] + public void Empty_Class_Should_Be_Cleared_When_Items_Added() + { + var target = new ItemsControl() + { + Template = this.GetTemplate(), + Items = new[] { 1, 2, 3 }, + }; + + Assert.False(target.Classes.Contains(":empty")); + } + + [Fact] + public void Empty_Class_Should_Be_Set_When_Empty_Collection_Set() + { + var target = new ItemsControl() + { + Template = this.GetTemplate(), + Items = new[] { 1, 2, 3 }, + }; + + target.Items = new int[0]; + + Assert.True(target.Classes.Contains(":empty")); + } + private ControlTemplate GetTemplate() { return ControlTemplate.Create(parent =>