diff --git a/src/Avalonia.Controls.TreeDataGrid/Selection/TreeSelectionModelBase.cs b/src/Avalonia.Controls.TreeDataGrid/Selection/TreeSelectionModelBase.cs index b161d3eb..d853d333 100644 --- a/src/Avalonia.Controls.TreeDataGrid/Selection/TreeSelectionModelBase.cs +++ b/src/Avalonia.Controls.TreeDataGrid/Selection/TreeSelectionModelBase.cs @@ -204,7 +204,7 @@ public bool IsSelected(IndexPath index) protected virtual bool TryGetItemAt(IndexPath index, out T? result) { - var items = (IReadOnlyList?)_root.ItemsView; + var items = (IEnumerable?)_root.ItemsView; var count = index.Count; for (var i = 0; i < count; ++i) @@ -215,17 +215,21 @@ protected virtual bool TryGetItemAt(IndexPath index, out T? result) return false; } - var j = index[i]; - - if (j < items.Count) + if (TryGetElementAt(items, index[i], out var item)) { if (i == count - 1) { - result = items[j]; + result = item; return true; } else - items = GetChildren(items[j]) as IReadOnlyList; + { + items = GetChildren(item); + } + } + else + { + break; } } @@ -566,6 +570,40 @@ internal static bool ShiftIndex(IndexPath parentIndex, int shiftIndex, int shift return false; } + private static bool TryGetElementAt(IEnumerable items, int index, [MaybeNullWhen(false)] out T result) + { + if (items is IList list) + { + if (index < list.Count) + { + result = list[index]; + return true; + } + } + else if (items is IReadOnlyList ro) + { + if (index < ro.Count) + { + result = ro[index]; + return true; + } + } + else + { + foreach (var item in items) + { + if (index-- == 0) + { + result = item; + return true; + } + } + } + + result = default; + return false; + } + public struct BatchUpdateOperation : IDisposable { private readonly TreeSelectionModelBase _owner;