Browse Source

Replaced AutoSelect with SelectionMode.

Added protected multiple selection properties to SelectingItemsControl.
pull/278/head
Steven Kirk 11 years ago
parent
commit
7b82df4369
  1. 2
      samples/TestApplication/Program.cs
  2. 2
      src/Perspex.Controls/Deck.cs
  3. 1
      src/Perspex.Controls/Perspex.Controls.csproj
  4. 65
      src/Perspex.Controls/Primitives/SelectingItemsControl.cs
  5. 2
      src/Perspex.Controls/Primitives/TabStrip.cs
  6. 34
      src/Perspex.Controls/SelectionMode.cs
  7. 2
      src/Perspex.Controls/TabControl.cs
  8. 20
      tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests_AutoSelect.cs

2
samples/TestApplication/Program.cs

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

2
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
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" />

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

2
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
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,
}
}

2
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);
}

20
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; }

Loading…
Cancel
Save