Browse Source

Don't raise SelectionModel.PropertyChanged during update.

pull/3936/head
Steven Kirk 6 years ago
parent
commit
7f87c2e74a
  1. 35
      src/Avalonia.Controls/SelectionModel.cs
  2. 54
      tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs

35
src/Avalonia.Controls/SelectionModel.cs

@ -20,6 +20,7 @@ namespace Avalonia.Controls
private bool _singleSelect;
private bool _autoSelect;
private int _operationCount;
private IndexPath _oldAnchorIndex;
private IReadOnlyList<IndexPath>? _selectedIndicesCached;
private IReadOnlyList<object?>? _selectedItemsCached;
private SelectionModelChildrenRequestedEventArgs? _childrenRequestedEventArgs;
@ -142,6 +143,8 @@ namespace Avalonia.Controls
}
set
{
var oldValue = AnchorIndex;
if (value != null)
{
SelectionTreeHelper.TraverseIndexPath(
@ -155,7 +158,10 @@ namespace Avalonia.Controls
_rootNode.AnchorIndex = -1;
}
RaisePropertyChanged("AnchorIndex");
if (_operationCount == 0 && oldValue != AnchorIndex)
{
RaisePropertyChanged("AnchorIndex");
}
}
}
@ -633,19 +639,18 @@ namespace Avalonia.Controls
_selectedIndicesCached = null;
_selectedItemsCached = null;
// Raise SelectionChanged event
if (e != null)
{
SelectionChanged?.Invoke(this, e);
}
RaisePropertyChanged(nameof(SelectedIndex));
RaisePropertyChanged(nameof(SelectedIndices));
RaisePropertyChanged(nameof(SelectedIndex));
RaisePropertyChanged(nameof(SelectedIndices));
if (_rootNode.Source != null)
{
RaisePropertyChanged(nameof(SelectedItem));
RaisePropertyChanged(nameof(SelectedItems));
if (_rootNode.Source != null)
{
RaisePropertyChanged(nameof(SelectedItem));
RaisePropertyChanged(nameof(SelectedItems));
}
}
}
@ -785,6 +790,7 @@ namespace Avalonia.Controls
{
if (_operationCount++ == 0)
{
_oldAnchorIndex = AnchorIndex;
_rootNode.BeginOperation();
}
}
@ -808,13 +814,16 @@ namespace Avalonia.Controls
var changeSet = new SelectionModelChangeSet(changes);
e = changeSet.CreateEventArgs();
}
}
OnSelectionChanged(e);
OnSelectionChanged(e);
if (_oldAnchorIndex != AnchorIndex)
{
RaisePropertyChanged(nameof(AnchorIndex));
}
if (_operationCount == 0)
{
_rootNode.Cleanup();
_oldAnchorIndex = default;
}
}

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

@ -1458,6 +1458,60 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(1, raised);
}
[Fact]
public void Batch_Update_Does_Not_Raise_PropertyChanged_Until_Operation_Finished()
{
var data = new[] { "foo", "bar", "baz", "qux" };
var target = new SelectionModel { Source = data };
var raised = 0;
target.SelectedIndex = new IndexPath(1);
Assert.Equal(new IndexPath(1), target.AnchorIndex);
target.PropertyChanged += (s, e) => ++raised;
using (target.Update())
{
target.ClearSelection();
Assert.Equal(0, raised);
target.AnchorIndex = new IndexPath(2);
Assert.Equal(0, raised);
target.SelectedIndex = new IndexPath(3);
Assert.Equal(0, raised);
}
Assert.Equal(new IndexPath(3), target.AnchorIndex);
Assert.Equal(5, raised);
}
[Fact]
public void Batch_Update_Does_Not_Raise_PropertyChanged_If_Nothing_Changed()
{
var data = new[] { "foo", "bar", "baz", "qux" };
var target = new SelectionModel { Source = data };
var raised = 0;
target.SelectedIndex = new IndexPath(1);
Assert.Equal(new IndexPath(1), target.AnchorIndex);
target.PropertyChanged += (s, e) => ++raised;
using (target.Update())
{
target.ClearSelection();
target.SelectedIndex = new IndexPath(1);
}
Assert.Equal(0, raised);
}
[Fact]
public void AutoSelect_Selects_When_Enabled()
{

Loading…
Cancel
Save