diff --git a/src/Avalonia.Controls/ISelectionModel.cs b/src/Avalonia.Controls/ISelectionModel.cs new file mode 100644 index 0000000000..aed21315bb --- /dev/null +++ b/src/Avalonia.Controls/ISelectionModel.cs @@ -0,0 +1,47 @@ +// This source file is adapted from the WinUI project. +// (https://github.com/microsoft/microsoft-ui-xaml) +// +// Licensed to The Avalonia Project under MIT License, courtesy of The .NET Foundation. + +using System; +using System.Collections.Generic; + +namespace Avalonia.Controls +{ + public interface ISelectionModel + { + IndexPath AnchorIndex { get; set; } + IndexPath SelectedIndex { get; set; } + IReadOnlyList SelectedIndices { get; } + object SelectedItem { get; } + IReadOnlyList SelectedItems { get; } + bool SingleSelect { get; set; } + object Source { get; set; } + + event EventHandler ChildrenRequested; + event EventHandler SelectionChanged; + + void ClearSelection(); + void Deselect(int index); + void Deselect(int groupIndex, int itemIndex); + void DeselectAt(IndexPath index); + void DeselectRange(IndexPath start, IndexPath end); + void DeselectRangeFromAnchor(int index); + void DeselectRangeFromAnchor(int endGroupIndex, int endItemIndex); + void DeselectRangeFromAnchorTo(IndexPath index); + void Dispose(); + bool? IsSelected(int index); + bool? IsSelected(int groupIndex, int itemIndex); + bool? IsSelectedAt(IndexPath index); + void Select(int index); + void Select(int groupIndex, int itemIndex); + void SelectAll(); + void SelectAt(IndexPath index); + void SelectRange(IndexPath start, IndexPath end); + void SelectRangeFromAnchor(int index); + void SelectRangeFromAnchor(int endGroupIndex, int endItemIndex); + void SelectRangeFromAnchorTo(IndexPath index); + void SetAnchorIndex(int index); + void SetAnchorIndex(int groupIndex, int index); + } +} diff --git a/src/Avalonia.Controls/SelectionModel.cs b/src/Avalonia.Controls/SelectionModel.cs index 8679b21c5f..303fc8766e 100644 --- a/src/Avalonia.Controls/SelectionModel.cs +++ b/src/Avalonia.Controls/SelectionModel.cs @@ -13,7 +13,7 @@ using Avalonia.Controls.Utils; namespace Avalonia.Controls { - public class SelectionModel : INotifyPropertyChanged, IDisposable + public class SelectionModel : ISelectionModel, INotifyPropertyChanged, IDisposable { private readonly SelectionNode _rootNode; private bool _singleSelect; @@ -335,7 +335,7 @@ namespace Avalonia.Controls _selectedIndicesCached = indices; } - return _selectedIndicesCached; + return _selectedIndicesCached; } } @@ -625,7 +625,7 @@ namespace Avalonia.Controls RaisePropertyChanged(nameof(SelectedIndex)); RaisePropertyChanged(nameof(SelectedIndices)); - + if (_rootNode.Source != null) { RaisePropertyChanged(nameof(SelectedItem)); @@ -641,7 +641,7 @@ namespace Avalonia.Controls } var selected = _rootNode.Select(index, select); - + if (selected) { AnchorIndex = new IndexPath(index); @@ -657,7 +657,7 @@ namespace Avalonia.Controls var childNode = _rootNode.GetAt(groupIndex, realizeChild: true); var selected = childNode!.Select(itemIndex, select); - + if (selected) { AnchorIndex = new IndexPath(groupIndex, itemIndex); @@ -667,7 +667,7 @@ namespace Avalonia.Controls private void SelectWithPathImpl(IndexPath index, bool select) { bool selected = false; - + if (_singleSelect) { ClearSelection(resetAnchor: true); @@ -696,7 +696,7 @@ namespace Avalonia.Controls { int anchorIndex = 0; var anchor = AnchorIndex; - + if (anchor != null) { anchorIndex = anchor.GetAt(0); @@ -710,7 +710,7 @@ namespace Avalonia.Controls var startGroupIndex = 0; var startItemIndex = 0; var anchorIndex = AnchorIndex; - + if (anchorIndex != null) { startGroupIndex = anchorIndex.GetAt(0);