Browse Source

Merge branch 'feature/selectionmodel-changed-notifications' into feature/selectionmodel-reset-handling

pull/3498/head
Steven Kirk 7 years ago
parent
commit
d3888e7e99
  1. 31
      src/Avalonia.Controls/SelectionModel.cs
  2. 27
      tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs

31
src/Avalonia.Controls/SelectionModel.cs

@ -17,6 +17,7 @@ namespace Avalonia.Controls
{
private readonly SelectionNode _rootNode;
private bool _singleSelect;
private int _operationCount;
private IReadOnlyList<IndexPath>? _selectedIndicesCached;
private IReadOnlyList<object?>? _selectedItemsCached;
private SelectionModelChildrenRequestedEventArgs? _childrenRequestedEventArgs;
@ -510,6 +511,8 @@ namespace Avalonia.Controls
ClearSelection(resetAnchor: true);
}
public IDisposable Update() => new Operation(this);
protected void OnPropertyChanged(string propertyName)
{
RaisePropertyChanged(propertyName);
@ -733,19 +736,33 @@ namespace Avalonia.Controls
});
}
private void BeginOperation() => _rootNode.BeginOperation();
private void BeginOperation()
{
if (_operationCount++ == 0)
{
_rootNode.BeginOperation();
}
}
private void EndOperation()
{
var changes = new List<SelectionNodeOperation>();
_rootNode.EndOperation(changes);
if (_operationCount == 0)
{
throw new AvaloniaInternalException("No selection operation in progress.");
}
SelectionModelSelectionChangedEventArgs? e = null;
if (changes.Count > 0)
if (--_operationCount == 0)
{
var changeSet = new SelectionModelChangeSet(changes);
e = changeSet.CreateEventArgs();
var changes = new List<SelectionNodeOperation>();
_rootNode.EndOperation(changes);
if (changes.Count > 0)
{
var changeSet = new SelectionModelChangeSet(changes);
e = changeSet.CreateEventArgs();
}
}
OnSelectionChanged(e);

27
tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs

@ -1641,6 +1641,33 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(3, raised);
Assert.Equal(new[] { new IndexPath(2) }, target.SelectedIndices);
}
[Fact]
public void Can_Batch_Update()
{
var target = new SelectionModel();
var raised = 0;
target.Source = Enumerable.Range(0, 10).ToList();
target.Select(1);
target.SelectionChanged += (s, e) =>
{
Assert.Equal(new[] { new IndexPath(1) }, e.DeselectedIndices);
Assert.Equal(new object[] { 1 }, e.DeselectedItems);
Assert.Equal(new[] { new IndexPath(4) }, e.SelectedIndices);
Assert.Equal(new object[] { 4 }, e.SelectedItems);
++raised;
};
using (target.Update())
{
target.Deselect(1);
target.Select(4);
}
Assert.Equal(1, raised);
}
private int GetSubscriberCount(AvaloniaList<object> list)
{

Loading…
Cancel
Save