Skip to content

Commit

Permalink
fix(ItemsControl): [Android] Adjust collection update reset for ComboBox
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromelaban committed Oct 19, 2021
1 parent 31c5cc9 commit 8581995
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Specialized;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Uno.UI.RuntimeTests.Helpers;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using static Private.Infrastructure.TestServices;
using System.Collections.ObjectModel;

#if NETFX_CORE
using Uno.UI.Extensions;
#elif __IOS__
Expand Down Expand Up @@ -314,5 +317,81 @@ public void When_Index_Is_Explicitly_Set_To_Negative_After_Out_Of_Range_Value()
comboBox.Items.Add(new ComboBoxItem());
Assert.AreEqual(-1, comboBox.SelectedIndex); // Will no longer become 2
}

[TestMethod]
public async Task When_Collection_Reset()
{
var SUT = new ComboBox();
try
{
WindowHelper.WindowContent = SUT;

var c = new MyObservableCollection<string>();
c.Add("One");
c.Add("Two");
c.Add("Three");

SUT.ItemsSource = c;

await WindowHelper.WaitForIdle();

Assert.AreEqual(SUT.Items.Count, 3);

using (c.BatchUpdate())
{
c.Add("Four");
c.Add("Five");
}

SUT.IsDropDownOpen = true;

// Items are materialized when the popup is opened
await WindowHelper.WaitForIdle();

Assert.AreEqual(SUT.Items.Count, 5);
Assert.IsNotNull(SUT.ContainerFromItem("One"));
Assert.IsNotNull(SUT.ContainerFromItem("Four"));
Assert.IsNotNull(SUT.ContainerFromItem("Five"));
}
finally
{
SUT.IsDropDownOpen = false;
}
}

public class MyObservableCollection<TType> : ObservableCollection<TType>
{
private int _batchUpdateCount;

public IDisposable BatchUpdate()
{
++_batchUpdateCount;

return Uno.Disposables.Disposable.Create(Release);

void Release()
{
if (--_batchUpdateCount <= 0)
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
}

protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (_batchUpdateCount > 0)
{
return;
}

base.OnCollectionChanged(e);
}

public void Append(TType item) => Add(item);

public TType GetAt(int index) => this[index];
}

}
}
42 changes: 42 additions & 0 deletions src/Uno.UI.Tests/Helpers/ObservableCollectionEx.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Uno.UI.Tests.Helpers
{
internal class ObservableCollectionEx<TType> : System.Collections.ObjectModel.ObservableCollection<TType>
{
private int _batchUpdateCount;

public IDisposable BatchUpdate()
{
++_batchUpdateCount;

return Uno.Disposables.Disposable.Create(Release);

void Release()
{
if (--_batchUpdateCount <= 0)
{
OnCollectionChanged(new System.Collections.Specialized.NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction.Reset));
}
}
}

protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (_batchUpdateCount > 0)
{
return;
}

base.OnCollectionChanged(e);
}

public void Append(TType item) => Add(item);

public TType GetAt(int index) => this[index];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,48 @@ public async Task When_ItemsSource_Changes_Items_VectorChanged_Triggered()
Assert.AreEqual(0, listView.Items.Count);
}

[TestMethod]
public async Task When_Collection_Reset()
{
var count = 0;
var panel = new StackPanel();

var SUT = new ItemsControl()
{
ItemsPanelRoot = panel,
ItemContainerStyle = BuildBasicContainerStyle(),
InternalItemsPanelRoot = panel,
ItemTemplate = new DataTemplate(() =>
{
count++;
return new Border();
})
};
SUT.ApplyTemplate();

var c = new ObservableCollectionEx<string>();
c.Add("One");
c.Add("Two");
c.Add("Three");

SUT.ItemsSource = c;
Assert.AreEqual(count, 3);

Assert.AreEqual(SUT.Items.Count, 3);

using (c.BatchUpdate())
{
c.Add("Four");
c.Add("Five");
}

Assert.AreEqual(SUT.Items.Count, 5);
Assert.AreEqual(count, 5);
Assert.IsNotNull(SUT.ContainerFromItem("One"));
Assert.IsNotNull(SUT.ContainerFromItem("Four"));
Assert.IsNotNull(SUT.ContainerFromItem("Five"));
}

private Style BuildBasicContainerStyle() =>
new Style(typeof(Windows.UI.Xaml.Controls.ListViewItem))
{
Expand Down
5 changes: 2 additions & 3 deletions src/Uno.UI/UI/Xaml/Controls/ItemsControl/ItemsControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,6 @@ protected virtual void OnItemsSourceChanged(DependencyPropertyChangedEventArgs e

IsGrouping = (e.NewValue as ICollectionView)?.CollectionGroups != null;
Items.SetItemsSource(UnwrapItemsSource() as IEnumerable);
UpdateItems(null);
ObserveCollectionChanged();
TryObserveCollectionViewSource(e.NewValue);
}
Expand Down Expand Up @@ -918,8 +917,8 @@ void LocalCleanupContainer(object container)
}

ItemsPanelRoot.Children.Clear();
RequestLayoutPartial();
return;

// Fall-through and materialize the call collection.
}
else if (args.Action == NotifyCollectionChangedAction.Remove
&& args.OldItems.Count == 1)
Expand Down

0 comments on commit 8581995

Please sign in to comment.