Browse Source
Merge pull request #5817 from AvaloniaUI/fixes/selecteditems-binding
Don't update SelectedItems when setting items source.
pull/5407/head
Steven Kirk
5 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with
56 additions and
6 deletions
-
src/Avalonia.Controls/Selection/InternalSelectionModel.cs
-
tests/Avalonia.Controls.UnitTests/ListBoxTests.cs
|
|
|
@ -80,10 +80,12 @@ namespace Avalonia.Controls.Selection |
|
|
|
try |
|
|
|
{ |
|
|
|
_ignoreSelectedItemsChanges = true; |
|
|
|
++_ignoreModelChanges; |
|
|
|
base.SetSource(value); |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
--_ignoreModelChanges; |
|
|
|
_ignoreSelectedItemsChanges = false; |
|
|
|
} |
|
|
|
|
|
|
|
@ -93,17 +95,14 @@ namespace Avalonia.Controls.Selection |
|
|
|
} |
|
|
|
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 |
|
|
|
{ |
|
|
|
@ -224,6 +223,7 @@ namespace Avalonia.Controls.Selection |
|
|
|
if (_isResetting) |
|
|
|
{ |
|
|
|
--_ignoreModelChanges; |
|
|
|
_isResetting = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -310,5 +310,27 @@ namespace Avalonia.Controls.Selection |
|
|
|
|
|
|
|
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(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -1,3 +1,4 @@ |
|
|
|
using System.Collections.ObjectModel; |
|
|
|
using System.Linq; |
|
|
|
using System.Reactive.Subjects; |
|
|
|
using Avalonia.Collections; |
|
|
|
@ -457,6 +458,33 @@ namespace Avalonia.Controls.UnitTests |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
[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) => |
|
|
|
|