TreeSelectioNode (and probably SelectionNodeBase) breaks when we try to Move a selection
heuristicAL opened this issue · 0 comments
I'm currently using DynamicData to populate, filter and sort the datasource for my TreeDataGrid. This all works wonderfully except when I try to change a field in the Grid which triggers re-sorting of that row. When the sort happens, it seems that the TreeSelectionNode
triggers OnSourceChanged
with a Moved
action with this value (only the index changes):
{
"Action": "Move",
"NewItems": [
<RowModel> // Same as OldItems
],
"NewStartingIndex": 0, // The sort is moving it to the top, as expected
"OldItems": [
<RowModel> // Same as NewItems
],
"OldStartingIndex": 10
}
The Moved
action throws a NotSupportedException
. From reading the OnSourceCollectionChanged method, it seems to me that this Move
action could potentially be easily implemented by using almost the same implementation as the one for Replaced
?
Willing to contribute to this if needed unless someone already has an idea of how to do this.
For reference, the best way to reproduce this is to create a DynamicData SourceCache and then sort it on a value that you then change.
Here is a reproduction of what I'm doing but in
ie:
using System.Collections.ObjectModel;
using System.Reactive.Linq;
using Avalonia.Controls;
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
public class Person(int Id, string Name, bool PinToTop) : ReactiveObject {
public int Id { get; init; } = Id;
public string Name { get; init; } = Name;
[Reactive] public bool PinToTop { get; init; } = PinToTop;
}
public class Program {
public static void Main() {
SourceCache<Person, int> test = new(x => x.Id);
test.Connect()
.AutoRefresh(model => model.PinToTop) // Re-evaluate the sort when this property is updated
.Sort(SortExpressionComparer<Person>.Descending(x => x.PinToTop).ThenByDescending(t => t.Name),
SortOptimisations.ComparesImmutableValuesOnly, 25)
.ObserveOn(RxApp.MainThreadScheduler)
.Bind(out ReadOnlyObservableCollection<Person> people);
var dataSource = new FlatTreeDataGridSource<Person>(people);
// Then use datasource from the view
}
}
Here are my package references:
<PackageReference Include="Avalonia.Controls.TreeDataGrid" Version="11.0.6" />
<PackageReference Include="DynamicData" Version="8.4.1" />
<PackageReference Include="ReactiveUI" Version="20.1.1" />
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
Environment:
TreeDataGrid Version: 11.0.2
Avalonia Version: 11.0.6
Operating System: Windows 10