Skip to content

Commit

Permalink
fix(reg): Fix SelectedIndex update when ItemsSource is ObservableColl…
Browse files Browse the repository at this point in the history
…ection

Fix regression introduced because we were 'double dipping' the collection changed event, both directly on the ItemsSource and via ItemsControl.Items.
  • Loading branch information
davidjohnoliver committed Aug 20, 2021
1 parent 6471ab2 commit 2747773
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,33 @@ public void When_ItemsSource_Grouped_Observables_Outer_Modified()
#endif
}

[TestMethod]
public void When_ItemsSource_ObservableCollection_Selection()
{
var itemsSource = new ObservableCollection<string>(Enumerable.Range(0, 80).Select(i => $"Item {i}"));
var SUT = new ListView { ItemsSource = itemsSource };

SUT.SelectedIndex = 5;

Assert.AreEqual(5, SUT.SelectedIndex);
Assert.AreEqual("Item 5", SUT.SelectedItem);

itemsSource.RemoveAt(2);

Assert.AreEqual(4, SUT.SelectedIndex);
Assert.AreEqual("Item 5", SUT.SelectedItem);

itemsSource.RemoveAt(22);

Assert.AreEqual(4, SUT.SelectedIndex);
Assert.AreEqual("Item 5", SUT.SelectedItem);

itemsSource.Insert(1, "Item 1.5");

Assert.AreEqual(5, SUT.SelectedIndex);
Assert.AreEqual("Item 5", SUT.SelectedItem);
}

private static ObservableCollection<GroupingObservableCollection<TKey, TElement>> GetGroupedObservable<TKey, TElement>(IEnumerable<TElement> source, Func<TElement, TKey> keySelector)
{
var observables = source.GroupBy(keySelector).Select(g => new GroupingObservableCollection<TKey, TElement>(g.Key, g));
Expand Down
14 changes: 9 additions & 5 deletions src/Uno.UI/UI/Xaml/Controls/Primitives/Selector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -507,10 +507,14 @@ internal virtual void OnItemClicked(int clickedIndex) { }

protected override void OnItemsChanged(object e)
{
if (e is IVectorChangedEventArgs iVCE)
if (
// When ItemsSource is set, we get collection changes from it directly (and it's not possible to directly modify Items)
ItemsSource == null &&
e is IVectorChangedEventArgs iVCE
)
{
if (iVCE.CollectionChange == CollectionChange.ItemChanged
|| (iVCE.CollectionChange == CollectionChange.ItemInserted && iVCE.Index < Items.Count))
|| (iVCE.CollectionChange == CollectionChange.ItemInserted && iVCE.Index < Items.Count))
{
var item = Items[(int)iVCE.Index];

Expand Down Expand Up @@ -624,7 +628,7 @@ protected void SetFocusedItem(int index,
FocusState focusState,
bool animateIfBringIntoView)
{

}

protected void SetFocusedItem(int index,
Expand Down Expand Up @@ -711,7 +715,7 @@ protected void SetFocusedItem(int index,

private void ScrollIntoView(int index, bool isGroupItemIndex, bool isHeader, bool isFooter, bool isFromPublicAPI, bool ensureContainerRealized, bool animateIfBringIntoView, ScrollIntoViewAlignment @default)
{

}

protected void SetFocusedItem(int index,
Expand Down Expand Up @@ -748,7 +752,7 @@ protected void SetFocusedItem(int index,
protected void SetFocusedItem(int index,
bool shouldScrollIntoView)
{

}

bool CanScrollIntoView()
Expand Down

0 comments on commit 2747773

Please sign in to comment.