|
|
|
@ -3,8 +3,10 @@ |
|
|
|
|
|
|
|
using System; |
|
|
|
using System.Collections; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.Specialized; |
|
|
|
using System.Linq; |
|
|
|
using Perspex.Collections; |
|
|
|
using Perspex.Controls.Generators; |
|
|
|
using Perspex.Input; |
|
|
|
using Perspex.Interactivity; |
|
|
|
@ -16,17 +18,8 @@ namespace Perspex.Controls.Primitives |
|
|
|
/// <summary>
|
|
|
|
/// An <see cref="ItemsControl"/> that maintains a selection.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
|
|
|
/// TODO: Support multiple selection.
|
|
|
|
/// </remarks>
|
|
|
|
public class SelectingItemsControl : ItemsControl |
|
|
|
{ |
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="AutoSelect"/> property.
|
|
|
|
/// </summary>
|
|
|
|
public static readonly PerspexProperty<bool> AutoSelectProperty = |
|
|
|
PerspexProperty.Register<SelectingItemsControl, bool>("AutoSelect"); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="SelectedIndex"/> property.
|
|
|
|
/// </summary>
|
|
|
|
@ -45,6 +38,21 @@ namespace Perspex.Controls.Primitives |
|
|
|
o => o.SelectedItem, |
|
|
|
(o, v) => o.SelectedItem = v); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="SelectedItems"/> property.
|
|
|
|
/// </summary>
|
|
|
|
protected static readonly PerspexProperty<IList<object>> SelectedItemsProperty = |
|
|
|
PerspexProperty.RegisterDirect<SelectingItemsControl, IList<object>>( |
|
|
|
nameof(SelectedItems), |
|
|
|
o => o.SelectedItems); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="SelectionMode"/> property.
|
|
|
|
/// </summary>
|
|
|
|
protected static readonly PerspexProperty<SelectionMode> SelectionModeProperty = |
|
|
|
PerspexProperty.Register<SelectingItemsControl, SelectionMode>( |
|
|
|
nameof(SelectionMode)); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Event that should be raised by items that implement <see cref="ISelectable"/> to
|
|
|
|
/// notify the parent <see cref="SelectingItemsControl"/> that their selection state
|
|
|
|
@ -55,6 +63,7 @@ namespace Perspex.Controls.Primitives |
|
|
|
|
|
|
|
private int _selectedIndex = -1; |
|
|
|
private object _selectedItem; |
|
|
|
private IList<object> _selectedItems; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Initializes static members of the <see cref="SelectingItemsControl"/> class.
|
|
|
|
@ -72,16 +81,7 @@ namespace Perspex.Controls.Primitives |
|
|
|
public SelectingItemsControl() |
|
|
|
{ |
|
|
|
ItemContainerGenerator.ContainersInitialized.Subscribe(ContainersInitialized); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets a value indicating whether the control should always try to keep an item
|
|
|
|
/// selected where possible.
|
|
|
|
/// </summary>
|
|
|
|
public bool AutoSelect |
|
|
|
{ |
|
|
|
get { return GetValue(AutoSelectProperty); } |
|
|
|
set { SetValue(AutoSelectProperty, value); } |
|
|
|
_selectedItems = new PerspexList<object>(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -118,6 +118,23 @@ namespace Perspex.Controls.Primitives |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the selected items.
|
|
|
|
/// </summary>
|
|
|
|
protected IList<object> SelectedItems |
|
|
|
{ |
|
|
|
get { return _selectedItems; } |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the selection mode.
|
|
|
|
/// </summary>
|
|
|
|
protected SelectionMode SelectionMode |
|
|
|
{ |
|
|
|
get { return GetValue(SelectionModeProperty); } |
|
|
|
set { SetValue(SelectionModeProperty, value); } |
|
|
|
} |
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
protected override void ItemsChanged(PerspexPropertyChangedEventArgs e) |
|
|
|
{ |
|
|
|
@ -127,7 +144,7 @@ namespace Perspex.Controls.Primitives |
|
|
|
{ |
|
|
|
SelectedIndex = IndexOf((IEnumerable)e.NewValue, SelectedItem); |
|
|
|
} |
|
|
|
else if (AutoSelect && Items != null & Items.Cast<object>().Any()) |
|
|
|
else if (SelectionMode == SelectionMode.SingleAlways && Items != null & Items.Cast<object>().Any()) |
|
|
|
{ |
|
|
|
SelectedIndex = 0; |
|
|
|
} |
|
|
|
@ -141,7 +158,7 @@ namespace Perspex.Controls.Primitives |
|
|
|
switch (e.Action) |
|
|
|
{ |
|
|
|
case NotifyCollectionChangedAction.Add: |
|
|
|
if (AutoSelect && SelectedIndex == -1) |
|
|
|
if (SelectionMode == SelectionMode.SingleAlways && SelectedIndex == -1) |
|
|
|
{ |
|
|
|
SelectedIndex = 0; |
|
|
|
} |
|
|
|
@ -155,7 +172,7 @@ namespace Perspex.Controls.Primitives |
|
|
|
if (selectedIndex >= e.OldStartingIndex && |
|
|
|
selectedIndex < e.OldStartingIndex + e.OldItems.Count) |
|
|
|
{ |
|
|
|
if (!AutoSelect) |
|
|
|
if (SelectionMode != SelectionMode.SingleAlways) |
|
|
|
{ |
|
|
|
SelectedIndex = -1; |
|
|
|
} |
|
|
|
@ -350,13 +367,13 @@ namespace Perspex.Controls.Primitives |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Called when the currently selected item is lost and the selection must be changed
|
|
|
|
/// depending on the <see cref="AutoSelect"/> property.
|
|
|
|
/// depending on the <see cref="SelectionMode"/> property.
|
|
|
|
/// </summary>
|
|
|
|
private void LostSelection() |
|
|
|
{ |
|
|
|
var items = Items?.Cast<object>(); |
|
|
|
|
|
|
|
if (items != null && AutoSelect) |
|
|
|
if (items != null && SelectionMode == SelectionMode.SingleAlways) |
|
|
|
{ |
|
|
|
var index = Math.Min(SelectedIndex, items.Count() - 1); |
|
|
|
|
|
|
|
|