Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TreeSelectioNode (and probably SelectionNodeBase) breaks when we try to Move a selection #297

Open
giard-alexandre opened this issue Jun 6, 2024 · 0 comments

Comments

@giard-alexandre
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant