13 changed files with 207 additions and 39 deletions
@ -0,0 +1,70 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="SelectableMixin.cs" company="Steven Kirk">
|
||||
|
// Copyright 2015 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls.Mixins |
||||
|
{ |
||||
|
using System; |
||||
|
using Perspex.Interactivity; |
||||
|
using Primitives; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Adds selectable functionality to control classes.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// <para>
|
||||
|
/// The <see cref="SelectableMixin{TControl}"/> adds behavior to a control which can be
|
||||
|
/// selected. It adds the following behavior:
|
||||
|
/// </para>
|
||||
|
/// <list type="bullet">
|
||||
|
/// <item>
|
||||
|
/// Raises an <see cref="SelectingItemsControl.IsSelectedChangedEvent"/> when the value if
|
||||
|
/// the IsSelected property changes.
|
||||
|
/// </item>
|
||||
|
/// <item>
|
||||
|
/// Adds a 'selected' class to selected controls.
|
||||
|
/// </item>
|
||||
|
/// </list>
|
||||
|
/// <para>
|
||||
|
/// Mixins apply themselves to classes and not instances, and as such should be created in
|
||||
|
/// a static constructor.
|
||||
|
/// </para>
|
||||
|
/// </remarks>
|
||||
|
public static class SelectableMixin |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="SelectableMixin{TControl}"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TControl">The control type.</typeparam>
|
||||
|
/// <param name="isSelected">The IsSelected property.</param>
|
||||
|
public static void Attach<TControl>(PerspexProperty<bool> isSelected) |
||||
|
where TControl : class, IControl |
||||
|
{ |
||||
|
Contract.Requires<ArgumentNullException>(isSelected != null); |
||||
|
|
||||
|
isSelected.Changed.Subscribe(x => |
||||
|
{ |
||||
|
var sender = x.Sender as TControl; |
||||
|
|
||||
|
if (sender != null) |
||||
|
{ |
||||
|
if ((bool)x.NewValue) |
||||
|
{ |
||||
|
sender.Classes.Add("selected"); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
sender.Classes.Remove("selected"); |
||||
|
} |
||||
|
|
||||
|
sender.RaiseEvent(new RoutedEventArgs |
||||
|
{ |
||||
|
RoutedEvent = SelectingItemsControl.IsSelectedChangedEvent |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,76 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="SelectableMixinTests.cs" company="Steven Kirk">
|
||||
|
// Copyright 2015 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls.UnitTests.Mixins |
||||
|
{ |
||||
|
using Perspex.Controls.Mixins; |
||||
|
using Perspex.Controls.Primitives; |
||||
|
using Xunit; |
||||
|
|
||||
|
public class SelectableMixinTests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void Selected_Class_Should_Not_Initially_Be_Added() |
||||
|
{ |
||||
|
var target = new TestControl(); |
||||
|
|
||||
|
Assert.Empty(target.Classes); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Setting_IsSelected_Should_Add_Selected_Class() |
||||
|
{ |
||||
|
var target = new TestControl(); |
||||
|
|
||||
|
target.IsSelected = true; |
||||
|
|
||||
|
Assert.Equal(new[] { "selected" }, target.Classes); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Clearing_IsSelected_Should_Remove_Selected_Class() |
||||
|
{ |
||||
|
var target = new TestControl(); |
||||
|
|
||||
|
target.IsSelected = true; |
||||
|
target.IsSelected = false; |
||||
|
|
||||
|
Assert.Empty(target.Classes); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Setting_IsSelected_Should_Raise_IsSelectedChangedEvent() |
||||
|
{ |
||||
|
var target = new TestControl(); |
||||
|
var raised = false; |
||||
|
|
||||
|
target.AddHandler( |
||||
|
SelectingItemsControl.IsSelectedChangedEvent, |
||||
|
(s, e) => raised = true); |
||||
|
|
||||
|
target.IsSelected = true; |
||||
|
|
||||
|
Assert.True(raised); |
||||
|
} |
||||
|
|
||||
|
private class TestControl : Control, ISelectable |
||||
|
{ |
||||
|
public static readonly PerspexProperty<bool> IsSelectedProperty = |
||||
|
PerspexProperty.Register<TestControl, bool>(nameof(IsSelected)); |
||||
|
|
||||
|
static TestControl() |
||||
|
{ |
||||
|
SelectableMixin.Attach<TestControl>(IsSelectedProperty); |
||||
|
} |
||||
|
|
||||
|
public bool IsSelected |
||||
|
{ |
||||
|
get { return this.GetValue(IsSelectedProperty); } |
||||
|
set { this.SetValue(IsSelectedProperty, value); } |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue