diff --git a/samples/BindingDemo/MainWindow.xaml b/samples/BindingDemo/MainWindow.xaml
index b57a9a0a9e..26a62ebca6 100644
--- a/samples/BindingDemo/MainWindow.xaml
+++ b/samples/BindingDemo/MainWindow.xaml
@@ -74,11 +74,11 @@
-
+
-
+
diff --git a/samples/BindingDemo/ViewModels/MainWindowViewModel.cs b/samples/BindingDemo/ViewModels/MainWindowViewModel.cs
index 22d01e0765..a66038ff3e 100644
--- a/samples/BindingDemo/ViewModels/MainWindowViewModel.cs
+++ b/samples/BindingDemo/ViewModels/MainWindowViewModel.cs
@@ -6,6 +6,7 @@ using System.Reactive.Linq;
using System.Threading.Tasks;
using System.Threading;
using ReactiveUI;
+using Avalonia.Controls;
namespace BindingDemo.ViewModels
{
@@ -27,7 +28,7 @@ namespace BindingDemo.ViewModels
Detail = "Item " + x + " details",
}));
- SelectedItems = new ObservableCollection();
+ Selection = new SelectionModel();
ShuffleItems = ReactiveCommand.Create(() =>
{
@@ -56,7 +57,7 @@ namespace BindingDemo.ViewModels
}
public ObservableCollection Items { get; }
- public ObservableCollection SelectedItems { get; }
+ public SelectionModel Selection { get; }
public ReactiveCommand ShuffleItems { get; }
public string BooleanString
diff --git a/samples/ControlCatalog/Pages/ListBoxPage.xaml b/samples/ControlCatalog/Pages/ListBoxPage.xaml
index b1b3112e60..47b4ce7151 100644
--- a/samples/ControlCatalog/Pages/ListBoxPage.xaml
+++ b/samples/ControlCatalog/Pages/ListBoxPage.xaml
@@ -10,7 +10,7 @@
HorizontalAlignment="Center"
Spacing="16">
-
+
diff --git a/samples/VirtualizationDemo/MainWindow.xaml b/samples/VirtualizationDemo/MainWindow.xaml
index 12137cd03d..4bd657bf93 100644
--- a/samples/VirtualizationDemo/MainWindow.xaml
+++ b/samples/VirtualizationDemo/MainWindow.xaml
@@ -45,7 +45,7 @@
SelectedItems { get; }
- = new AvaloniaList();
+ public SelectionModel Selection { get; } = new SelectionModel();
public AvaloniaList Items
{
@@ -141,9 +140,9 @@ namespace VirtualizationDemo.ViewModels
{
var index = Items.Count;
- if (SelectedItems.Count > 0)
+ if (Selection.SelectedIndices.Count > 0)
{
- index = Items.IndexOf(SelectedItems[0]);
+ index = Selection.SelectedIndex.GetAt(0);
}
Items.Insert(index, new ItemViewModel(_newItemIndex++, NewItemString));
@@ -151,9 +150,9 @@ namespace VirtualizationDemo.ViewModels
private void Remove()
{
- if (SelectedItems.Count > 0)
+ if (Selection.SelectedItems.Count > 0)
{
- Items.RemoveAll(SelectedItems);
+ Items.RemoveAll(Selection.SelectedItems.Cast().ToList());
}
}
@@ -167,8 +166,7 @@ namespace VirtualizationDemo.ViewModels
private void SelectItem(int index)
{
- SelectedItems.Clear();
- SelectedItems.Add(Items[index]);
+ Selection.SelectedIndex = new IndexPath(index);
}
}
}
diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs
index c2cf20b32d..0722802962 100644
--- a/src/Avalonia.Controls/ComboBox.cs
+++ b/src/Avalonia.Controls/ComboBox.cs
@@ -289,9 +289,9 @@ namespace Avalonia.Controls
{
var container = ItemContainerGenerator.ContainerFromIndex(selectedIndex);
- if (container == null && SelectedItems.Count > 0)
+ if (container == null && SelectedIndex != -1)
{
- ScrollIntoView(SelectedItems[0]);
+ ScrollIntoView(Selection.SelectedItem);
container = ItemContainerGenerator.ContainerFromIndex(selectedIndex);
}
diff --git a/src/Avalonia.Controls/ListBox.cs b/src/Avalonia.Controls/ListBox.cs
index 4966e669ed..a15aedd621 100644
--- a/src/Avalonia.Controls/ListBox.cs
+++ b/src/Avalonia.Controls/ListBox.cs
@@ -34,6 +34,12 @@ namespace Avalonia.Controls
public static readonly new DirectProperty SelectedItemsProperty =
SelectingItemsControl.SelectedItemsProperty;
+ ///
+ /// Defines the property.
+ ///
+ public static readonly new DirectProperty SelectionProperty =
+ SelectingItemsControl.SelectionProperty;
+
///
/// Defines the property.
///
@@ -73,6 +79,15 @@ namespace Avalonia.Controls
set => base.SelectedItems = value;
}
+ ///
+ /// Gets or sets a model holding the current selection.
+ ///
+ public new ISelectionModel Selection
+ {
+ get => base.Selection;
+ set => base.Selection = value;
+ }
+
///
/// Gets or sets the selection mode.
///
@@ -98,12 +113,12 @@ namespace Avalonia.Controls
///
/// Selects all items in the .
///
- public new void SelectAll() => base.SelectAll();
+ public void SelectAll() => Selection.SelectAll();
///
/// Deselects all items in the .
///
- public new void UnselectAll() => base.UnselectAll();
+ public void UnselectAll() => Selection.ClearSelection();
///
protected override IItemContainerGenerator CreateItemContainerGenerator()
diff --git a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs
index 6bc4e71508..b1a4379cae 100644
--- a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs
+++ b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs
@@ -5,15 +5,15 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
+using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
-using Avalonia.Collections;
using Avalonia.Controls.Generators;
+using Avalonia.Controls.Utils;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Interactivity;
-using Avalonia.Logging;
using Avalonia.VisualTree;
namespace Avalonia.Controls.Primitives
@@ -26,9 +26,9 @@ namespace Avalonia.Controls.Primitives
/// provides a base class for s
/// that maintain a selection (single or multiple). By default only its
/// and properties are visible; the
- /// current multiple selection together with the
- /// properties are protected, however a derived class can expose
- /// these if it wishes to support multiple selection.
+ /// current multiple and together with the
+ /// and properties are protected, however a derived class can
+ /// expose these if it wishes to support multiple selection.
///
///
/// maintains a selection respecting the current
@@ -77,6 +77,15 @@ namespace Avalonia.Controls.Primitives
o => o.SelectedItems,
(o, v) => o.SelectedItems = v);
+ ///
+ /// Defines the property.
+ ///
+ public static readonly DirectProperty SelectionProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(Selection),
+ o => o.Selection,
+ (o, v) => o.Selection = v);
+
///
/// Defines the property.
///
@@ -103,17 +112,22 @@ namespace Avalonia.Controls.Primitives
RoutingStrategies.Bubble);
private static readonly IList Empty = Array.Empty