diff --git a/src/Avalonia.Controls/SelectionModel.cs b/src/Avalonia.Controls/SelectionModel.cs index 72d54d96e1..a2b080efc4 100644 --- a/src/Avalonia.Controls/SelectionModel.cs +++ b/src/Avalonia.Controls/SelectionModel.cs @@ -561,7 +561,7 @@ namespace Avalonia.Controls ApplyAutoSelect(); } - internal object? ResolvePath(object data, SelectionNode sourceNode) + internal object? ResolvePath(object data, IndexPath dataIndexPath) { object? resolved = null; @@ -570,18 +570,18 @@ namespace Avalonia.Controls { if (_childrenRequestedEventArgs == null) { - _childrenRequestedEventArgs = new SelectionModelChildrenRequestedEventArgs(data, sourceNode); + _childrenRequestedEventArgs = new SelectionModelChildrenRequestedEventArgs(data, dataIndexPath, false); } else { - _childrenRequestedEventArgs.Initialize(data, sourceNode); + _childrenRequestedEventArgs.Initialize(data, dataIndexPath, false); } ChildrenRequested(this, _childrenRequestedEventArgs); resolved = _childrenRequestedEventArgs.Children; // Clear out the values in the args so that it cannot be used after the event handler call. - _childrenRequestedEventArgs.Initialize(null, null); + _childrenRequestedEventArgs.Initialize(null, default, true); } else { diff --git a/src/Avalonia.Controls/SelectionModelChildrenRequestedEventArgs.cs b/src/Avalonia.Controls/SelectionModelChildrenRequestedEventArgs.cs index aa5a9b5cad..823e7b9447 100644 --- a/src/Avalonia.Controls/SelectionModelChildrenRequestedEventArgs.cs +++ b/src/Avalonia.Controls/SelectionModelChildrenRequestedEventArgs.cs @@ -12,12 +12,16 @@ namespace Avalonia.Controls public class SelectionModelChildrenRequestedEventArgs : EventArgs { private object? _source; - private SelectionNode? _sourceNode; - - internal SelectionModelChildrenRequestedEventArgs(object source, SelectionNode sourceNode) + private IndexPath _sourceIndexPath; + private bool _throwOnAccess; + + internal SelectionModelChildrenRequestedEventArgs( + object source, + IndexPath sourceIndexPath, + bool throwOnAccess) { - _source = source; - _sourceNode = sourceNode; + source = source ?? throw new ArgumentNullException(nameof(source)); + Initialize(source, sourceIndexPath, throwOnAccess); } public object? Children { get; set; } @@ -26,12 +30,12 @@ namespace Avalonia.Controls { get { - if (_source == null) + if (_throwOnAccess) { throw new ObjectDisposedException(nameof(SelectionModelChildrenRequestedEventArgs)); } - return _source; + return _source!; } } @@ -39,19 +43,28 @@ namespace Avalonia.Controls { get { - if (_sourceNode == null) + if (_throwOnAccess) { throw new ObjectDisposedException(nameof(SelectionModelChildrenRequestedEventArgs)); } - return _sourceNode.IndexPath; + return _sourceIndexPath; } } - internal void Initialize(object? source, SelectionNode? sourceNode) + internal void Initialize( + object? source, + IndexPath sourceIndexPath, + bool throwOnAccess) { + if (!throwOnAccess && source == null) + { + throw new ArgumentNullException(nameof(source)); + } + _source = source; - _sourceNode = sourceNode; + _sourceIndexPath = sourceIndexPath; + _throwOnAccess = throwOnAccess; } } } diff --git a/src/Avalonia.Controls/SelectionNode.cs b/src/Avalonia.Controls/SelectionNode.cs index 562cbdddae..136964b5b1 100644 --- a/src/Avalonia.Controls/SelectionNode.cs +++ b/src/Avalonia.Controls/SelectionNode.cs @@ -166,7 +166,8 @@ namespace Avalonia.Controls if (childData != null) { - var resolvedChild = _manager.ResolvePath(childData, this); + var childDataIndexPath = IndexPath.CloneWithChildIndex(index); + var resolvedChild = _manager.ResolvePath(childData, childDataIndexPath); if (resolvedChild != null) { diff --git a/tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs b/tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs index d1e683b9cd..bbba360a44 100644 --- a/tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs +++ b/tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs @@ -278,21 +278,21 @@ namespace Avalonia.Controls.UnitTests // Validate SourceIndices. var expectedSourceIndices = new List() { - Path(), Path(1), Path(1, 0), - Path(1), - Path(1, 0, 1), - Path(1, 0, 1), - Path(1, 0, 1), Path(1, 0, 1), Path(1, 1), - Path(1, 1), - Path(1, 1, 0), - Path(1, 1, 0), - Path(1, 1, 0), + Path(1, 0, 1, 3), + Path(1, 0, 1, 2), + Path(1, 0, 1, 1), + Path(1, 0, 1, 0), + Path(1, 1, 1), Path(1, 1, 0), - Path(1, 1, 1) + Path(1, 1, 0, 3), + Path(1, 1, 0, 2), + Path(1, 1, 0, 1), + Path(1, 1, 0, 0), + Path(1, 1, 1, 0) }; Assert.Equal(expectedSourceIndices.Count, sourcePaths.Count);