Browse Source

Added ISelectionModel.

pull/3469/head
Steven Kirk 7 years ago
parent
commit
c8f0bec40d
  1. 47
      src/Avalonia.Controls/ISelectionModel.cs
  2. 21
      src/Avalonia.Controls/SelectionModel.cs

47
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<IndexPath> SelectedIndices { get; }
object SelectedItem { get; }
IReadOnlyList<object> SelectedItems { get; }
bool SingleSelect { get; set; }
object Source { get; set; }
event EventHandler<SelectionModelChildrenRequestedEventArgs> ChildrenRequested;
event EventHandler<SelectionModelSelectionChangedEventArgs> 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);
}
}

21
src/Avalonia.Controls/SelectionModel.cs

@ -12,7 +12,7 @@ using Avalonia.Controls.Utils;
namespace Avalonia.Controls namespace Avalonia.Controls
{ {
public class SelectionModel : INotifyPropertyChanged, IDisposable public class SelectionModel : ISelectionModel, INotifyPropertyChanged, IDisposable
{ {
private readonly SelectionNode _rootNode; private readonly SelectionNode _rootNode;
private bool _singleSelect; private bool _singleSelect;
@ -72,7 +72,6 @@ namespace Avalonia.Controls
} }
} }
public IndexPath AnchorIndex public IndexPath AnchorIndex
{ {
get get
@ -184,7 +183,7 @@ namespace Avalonia.Controls
// the selected item at a particular index. This avoid having to create the storage and copying // the selected item at a particular index. This avoid having to create the storage and copying
// needed in a dumb vector. This also allows us to expose a tree of selected nodes into an // needed in a dumb vector. This also allows us to expose a tree of selected nodes into an
// easier to consume flat vector view of objects. // easier to consume flat vector view of objects.
var selectedItems = new SelectedItems<object?> ( var selectedItems = new SelectedItems<object?>(
selectedInfos, selectedInfos,
(infos, index) => (infos, index) =>
{ {
@ -284,7 +283,7 @@ namespace Avalonia.Controls
_selectedIndicesCached = indices; _selectedIndicesCached = indices;
} }
return _selectedIndicesCached; return _selectedIndicesCached;
} }
} }
@ -455,7 +454,7 @@ namespace Avalonia.Controls
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} }
public void OnSelectionInvalidatedDueToCollectionChange() internal void OnSelectionInvalidatedDueToCollectionChange()
{ {
OnSelectionChanged(); OnSelectionChanged();
} }
@ -535,7 +534,7 @@ namespace Avalonia.Controls
RaisePropertyChanged(nameof(SelectedIndex)); RaisePropertyChanged(nameof(SelectedIndex));
RaisePropertyChanged(nameof(SelectedIndices)); RaisePropertyChanged(nameof(SelectedIndices));
if (_rootNode.Source != null) if (_rootNode.Source != null)
{ {
RaisePropertyChanged(nameof(SelectedItem)); RaisePropertyChanged(nameof(SelectedItem));
@ -551,7 +550,7 @@ namespace Avalonia.Controls
} }
var selected = _rootNode.Select(index, select); var selected = _rootNode.Select(index, select);
if (selected) if (selected)
{ {
AnchorIndex = new IndexPath(index); AnchorIndex = new IndexPath(index);
@ -569,7 +568,7 @@ namespace Avalonia.Controls
var childNode = _rootNode.GetAt(groupIndex, realizeChild: true); var childNode = _rootNode.GetAt(groupIndex, realizeChild: true);
var selected = childNode!.Select(itemIndex, select); var selected = childNode!.Select(itemIndex, select);
if (selected) if (selected)
{ {
AnchorIndex = new IndexPath(groupIndex, itemIndex); AnchorIndex = new IndexPath(groupIndex, itemIndex);
@ -581,7 +580,7 @@ namespace Avalonia.Controls
private void SelectWithPathImpl(IndexPath index, bool select, bool raiseSelectionChanged) private void SelectWithPathImpl(IndexPath index, bool select, bool raiseSelectionChanged)
{ {
bool selected = false; bool selected = false;
if (_singleSelect) if (_singleSelect)
{ {
ClearSelection(resetAnchor: true, raiseSelectionChanged: false); ClearSelection(resetAnchor: true, raiseSelectionChanged: false);
@ -615,7 +614,7 @@ namespace Avalonia.Controls
{ {
int anchorIndex = 0; int anchorIndex = 0;
var anchor = AnchorIndex; var anchor = AnchorIndex;
if (anchor != null) if (anchor != null)
{ {
anchorIndex = anchor.GetAt(0); anchorIndex = anchor.GetAt(0);
@ -634,7 +633,7 @@ namespace Avalonia.Controls
var startGroupIndex = 0; var startGroupIndex = 0;
var startItemIndex = 0; var startItemIndex = 0;
var anchorIndex = AnchorIndex; var anchorIndex = AnchorIndex;
if (anchorIndex != null) if (anchorIndex != null)
{ {
startGroupIndex = anchorIndex.GetAt(0); startGroupIndex = anchorIndex.GetAt(0);

Loading…
Cancel
Save