Skip to content

Commit

Permalink
Merge branch 'master' into fixes/do-not-obsolete-context-menu-api
Browse files Browse the repository at this point in the history
  • Loading branch information
grokys committed Apr 21, 2021
2 parents 48fd593 + 222860c commit ab1bf41
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 6 deletions.
34 changes: 28 additions & 6 deletions src/Avalonia.Controls/Selection/InternalSelectionModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,12 @@ private protected override void SetSource(IEnumerable? value)
try
{
_ignoreSelectedItemsChanges = true;
++_ignoreModelChanges;
base.SetSource(value);
}
finally
{
--_ignoreModelChanges;
_ignoreSelectedItemsChanges = false;
}

Expand All @@ -93,17 +95,14 @@ private protected override void SetSource(IEnumerable? value)
}
else
{
foreach (var i in oldSelection)
{
var index = ItemsView!.IndexOf(i);
Select(index);
}
SyncFromSelectedItems();
}
}

private void SyncToSelectedItems()
{
if (_writableSelectedItems is object)
if (_writableSelectedItems is object &&
!SequenceEqual(_writableSelectedItems, base.SelectedItems))
{
try
{
Expand Down Expand Up @@ -224,6 +223,7 @@ protected override void OnSourceCollectionChangeFinished()
if (_isResetting)
{
--_ignoreModelChanges;
_isResetting = false;
}
}

Expand Down Expand Up @@ -310,5 +310,27 @@ private static int IndexOf(object? source, object? item)

return -1;
}

private static bool SequenceEqual(IList first, IReadOnlyList<object?> second)
{
if (first is IEnumerable<object?> e)
{
return e.SequenceEqual(second);
}

var comparer = EqualityComparer<object?>.Default;
var e1 = first.GetEnumerator();
using var e2 = second.GetEnumerator();

while (e1.MoveNext())
{
if (!(e2.MoveNext() && comparer.Equals(e1.Current, e2.Current)))
{
return false;
}
}

return !e2.MoveNext();
}
}
}
28 changes: 28 additions & 0 deletions tests/Avalonia.Controls.UnitTests/ListBoxTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Subjects;
using Avalonia.Collections;
Expand Down Expand Up @@ -457,6 +458,33 @@ public void Adding_And_Selecting_Item_With_AutoScrollToSelectedItem_Should_NotHi
}
}

[Fact]
public void Initial_Binding_Of_SelectedItems_Should_Not_Cause_Write_To_SelectedItems()
{
var target = new ListBox
{
[!ListBox.ItemsProperty] = new Binding("Items"),
[!ListBox.SelectedItemsProperty] = new Binding("SelectedItems"),
};

var viewModel = new
{
Items = new[] { "Foo", "Bar", "Baz " },
SelectedItems = new ObservableCollection<string> { "Bar" },
};

var raised = 0;

viewModel.SelectedItems.CollectionChanged += (s, e) => ++raised;

target.DataContext = viewModel;

Assert.Equal(0, raised);
Assert.Equal(new[] { "Bar" }, viewModel.SelectedItems);
Assert.Equal(new[] { "Bar" }, target.SelectedItems);
Assert.Equal(new[] { "Bar" }, target.Selection.SelectedItems);
}

private FuncControlTemplate ListBoxTemplate()
{
return new FuncControlTemplate<ListBox>((parent, scope) =>
Expand Down

0 comments on commit ab1bf41

Please sign in to comment.