AvaloniaUI / Avalonia.Controls.TreeDataGrid

A combined TreeView/DataGrid for Avalonia.
MIT License
266 stars 54 forks source link

The items are not sorted after setting column SortDirection, despite the column header shows arrow. #271

Open sinatrocious opened 6 months ago

sinatrocious commented 6 months ago

Describe the bug

I am setting column SortDirection in code, but the sorting is not happening. Sorting seems to only works if I click column header.

To Reproduce

  1. Create new avalonia desktop application.
  2. Add Avalonia.Controls.TreeDataGrid nuget.
  3. Do following changes :
Repro App.axaml ```axaml ``` MainViewModel.cs ```c# public class MainViewModel : ViewModelBase { public AvaloniaList Items { get; } = new(); public HierarchicalTreeDataGridSource Source { get; } public ReactiveCommand Command { get; } public MainViewModel() { Source = new(Items) { Columns = { new HierarchicalExpanderColumn(new TextColumn("N", o => o.N), o => o.Chilren) { SortDirection = ListSortDirection.Ascending } } }; Command = ReactiveCommand.Create(() => Items.Add(new())); } } public class Item { public int N { get; } public AvaloniaList Chilren { get; } = []; public Item() => N = Random.Shared.Next(10); } ``` MainView.axaml ```xaml
  1. Run, click button several time and observe issue:

TreeDataGrid SortDirection bug

Expected behavior

I expect sorting to work according to SortDirection.

Environment

Additional context

I've tried to set SortDirection after 5s delay after window is shown. The column header will show arrow, but no sorting occurs. I guess this public property is used internally to toggle displaying of arrow, but then how do I force sorting?

I guess simulating mouse click on column header is a workaround, but after quick research I am unable to find anything what can help me to build such workaround.

sinatrocious commented 6 months ago

Possible workaround is to send click event to first column:

var firstColumn = Children<TreeDataGridColumnHeader>(treeDataGrid).First();
firstColumn.RaiseEvent(new RoutedEventArgs { RoutedEvent = Button.ClickEvent });
Children method ```c# IEnumerable Children(Visual parent) { foreach (var child in parent.GetVisualChildren()) { if (child is T target) yield return target; foreach (T item in Children(child)) yield return item; } } ```