Jelajahi Sumber

Replaced AutoSelect with SelectionMode.

Added protected multiple selection properties to SelectingItemsControl.
Steven Kirk 10 tahun lalu
induk
melakukan
7b82df4369

+ 0 - 2
samples/TestApplication/Program.cs

@@ -483,8 +483,6 @@ namespace TestApplication
 				}
 			};
 
-			imageDeck.AutoSelect = true;
-
 			var next = new Button 
 			{
 				VerticalAlignment = VerticalAlignment.Center,

+ 1 - 1
src/Perspex.Controls/Deck.cs

@@ -31,7 +31,7 @@ namespace Perspex.Controls
         /// </summary>
         static Deck()
         {
-            AutoSelectProperty.OverrideDefaultValue<Deck>(true);
+            SelectionModeProperty.OverrideDefaultValue<Deck>(SelectionMode.SingleAlways);
             ItemsPanelProperty.OverrideDefaultValue<Deck>(PanelTemplate);
         }
 

+ 1 - 0
src/Perspex.Controls/Perspex.Controls.csproj

@@ -44,6 +44,7 @@
     <Compile Include="DockPanel.cs" />
     <Compile Include="HotkeyManager.cs" />
     <Compile Include="Platform\ITopLevelRenderer.cs" />
+    <Compile Include="SelectionMode.cs" />
     <Compile Include="SystemDialog.cs" />
     <Compile Include="Generators\ITreeItemContainerGenerator.cs" />
     <Compile Include="Generators\ItemContainers.cs" />

+ 41 - 24
src/Perspex.Controls/Primitives/SelectingItemsControl.cs

@@ -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);
 

+ 1 - 1
src/Perspex.Controls/Primitives/TabStrip.cs

@@ -15,7 +15,7 @@ namespace Perspex.Controls.Primitives
 
         static TabStrip()
         {
-            AutoSelectProperty.OverrideDefaultValue<TabStrip>(true);
+            SelectionModeProperty.OverrideDefaultValue<TabStrip>(SelectionMode.SingleAlways);
             FocusableProperty.OverrideDefaultValue(typeof(TabStrip), false);
         }
 

+ 34 - 0
src/Perspex.Controls/SelectionMode.cs

@@ -0,0 +1,34 @@
+// Copyright (c) The Perspex Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+namespace Perspex.Controls
+{
+    /// <summary>
+    /// Defines the selection mode for a control which can select multiple items.
+    /// </summary>
+    public enum SelectionMode
+    {
+        /// <summary>
+        /// One item can be selected at a time.
+        /// </summary>
+        Single,
+
+        /// <summary>
+        /// One item can be selected at a time, and there will always be a selected item as long
+        /// as there are items to select.
+        /// </summary>
+        SingleAlways,
+
+        /// <summary>
+        /// Multiple items can be selected and their selection state is toggled by presses or by 
+        /// pressing the spacebar.
+        /// </summary>
+        MultipleToggle,
+
+        /// <summary>
+        /// A range of items can be selected by holding the shift key, and individual items can be
+        /// selected by holding the ctrl key.
+        /// </summary>
+        MultipleRange,
+    }
+}

+ 1 - 1
src/Perspex.Controls/TabControl.cs

@@ -33,7 +33,7 @@ namespace Perspex.Controls
         /// </summary>
         static TabControl()
         {
-            AutoSelectProperty.OverrideDefaultValue<TabControl>(true);
+            SelectionModeProperty.OverrideDefaultValue<TabControl>(SelectionMode.SingleAlways);
             FocusableProperty.OverrideDefaultValue<TabControl>(false);
             SelectedIndexProperty.Changed.AddClassHandler<TabControl>(x => x.SelectedIndexChanged);
         }

+ 12 - 8
tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests_AutoSelect.cs

@@ -14,9 +14,8 @@ namespace Perspex.Controls.UnitTests.Primitives
         [Fact]
         public void First_Item_Should_Be_Selected()
         {
-            var target = new SelectingItemsControl
+            var target = new TestSelector
             {
-                AutoSelect = true,
                 Items = new[] { "foo", "bar" },
                 Template = Template(),
             };
@@ -31,9 +30,8 @@ namespace Perspex.Controls.UnitTests.Primitives
         public void First_Item_Should_Be_Selected_When_Added()
         {
             var items = new PerspexList<string>();
-            var target = new SelectingItemsControl
+            var target = new TestSelector
             {
-                AutoSelect = true,
                 Items = items,
                 Template = Template(),
             };
@@ -50,9 +48,8 @@ namespace Perspex.Controls.UnitTests.Primitives
         {
             var items = new PerspexList<string>(new[] { "foo", "bar", "baz", "qux" });
 
-            var target = new SelectingItemsControl
+            var target = new TestSelector
             {
-                AutoSelect = true,
                 Items = items,
                 Template = Template(),
             };
@@ -70,9 +67,8 @@ namespace Perspex.Controls.UnitTests.Primitives
         {
             var items = new PerspexList<string>(new[] { "foo", "bar" });
 
-            var target = new SelectingItemsControl
+            var target = new TestSelector
             {
-                AutoSelect = true,
                 Items = items,
                 Template = Template(),
             };
@@ -97,6 +93,14 @@ namespace Perspex.Controls.UnitTests.Primitives
                 });
         }
 
+        private class TestSelector : SelectingItemsControl
+        {
+            static TestSelector()
+            {
+                SelectionModeProperty.OverrideDefaultValue<TestSelector>(SelectionMode.SingleAlways);
+            }
+        }
+
         private class Item : Control, ISelectable
         {
             public bool IsSelected { get; set; }