Browse Source

Expose API for batch updates.

pull/3470/head
Steven Kirk 6 years ago
parent
commit
44cf7f24db
  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;
@ -509,6 +510,8 @@ namespace Avalonia.Controls
ClearSelection(resetAnchor: true);
}
public IDisposable Update() => new Operation(this);
protected void OnPropertyChanged(string propertyName)
{
RaisePropertyChanged(propertyName);
@ -732,19 +735,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

@ -1466,6 +1466,33 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(1, raised);
}
[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)
{
return ((INotifyCollectionChangedDebug)list).GetCollectionChangedSubscribers()?.Length ?? 0;

Loading…
Cancel
Save