From 95190e168b49f2eaf2ad5471e1931f8c0b45420f Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sat, 15 Feb 2020 10:02:15 +0100 Subject: [PATCH] Fixed SelectionModelChildrenRequestedEventArgs returning incorrect so... MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …urce index fixed sourceindex childrenrequested args Port of https://github.com/microsoft/microsoft-ui-xaml/commit/ee03bace144e3a37650df0536955f5f658dd2aad --- src/Avalonia.Controls/SelectionModel.cs | 8 ++--- ...electionModelChildrenRequestedEventArgs.cs | 35 +++++++++++++------ src/Avalonia.Controls/SelectionNode.cs | 3 +- .../SelectionModelTests.cs | 20 +++++------ 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/Avalonia.Controls/SelectionModel.cs b/src/Avalonia.Controls/SelectionModel.cs index 325e2e8848..d55faf53f3 100644 --- a/src/Avalonia.Controls/SelectionModel.cs +++ b/src/Avalonia.Controls/SelectionModel.cs @@ -459,7 +459,7 @@ namespace Avalonia.Controls OnSelectionChanged(); } - internal object? ResolvePath(object data, SelectionNode sourceNode) + internal object? ResolvePath(object data, IndexPath dataIndexPath) { object? resolved = null; @@ -468,18 +468,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 5bfa76f83f..bf21a5f2d1 100644 --- a/src/Avalonia.Controls/SelectionNode.cs +++ b/src/Avalonia.Controls/SelectionNode.cs @@ -128,7 +128,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 31e07d834a..3233059718 100644 --- a/tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs +++ b/tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs @@ -277,21 +277,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);