42 changed files with 1413 additions and 602 deletions
@ -0,0 +1,29 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<package> |
||||
|
<metadata> |
||||
|
<id>Perspex.Desktop</id> |
||||
|
<version>#VERSION#</version> |
||||
|
<authors>Perspex Team</authors> |
||||
|
<owners>stevenk</owners> |
||||
|
<licenseUrl>http://opensource.org/licenses/MIT</licenseUrl> |
||||
|
<projectUrl>https://github.com/Perspex/Perspex/</projectUrl> |
||||
|
<requireLicenseAcceptance>false</requireLicenseAcceptance> |
||||
|
<description>The Perspex UI framework</description> |
||||
|
<releaseNotes></releaseNotes> |
||||
|
<copyright>Copyright 2015</copyright> |
||||
|
<tags>Perspex</tags> |
||||
|
<dependencies> |
||||
|
<dependency id="Serilog" version="1.5.9" /> |
||||
|
<dependency id="Splat" version="1.6.2" /> |
||||
|
<dependency id="Sprache" version="2.0.0.47" /> |
||||
|
<dependency id="Rx-Core" version="2.2.5" /> |
||||
|
<dependency id="Rx-Interfaces" version="2.2.5" /> |
||||
|
<dependency id="Rx-Linq" version="2.2.5" /> |
||||
|
<dependency id="Rx-Main" version="2.2.5" /> |
||||
|
<dependency id="Rx-PlatformServices" version="2.2.5" /> |
||||
|
<dependency id="SharpDX" version="2.6.3"/> |
||||
|
<dependency id="SharpDX.Direct2D1" version="2.6.3"/> |
||||
|
<dependency id="SharpDX.DXGI" version="2.6.3"/> |
||||
|
</dependencies> |
||||
|
</metadata> |
||||
|
</package> |
||||
@ -1,11 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
|
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|
||||
<ItemGroup Condition="'$(MSBuildThisFileDirectory)' != '' And HasTrailingSlash('$(MSBuildThisFileDirectory)')"> |
|
||||
<PlatformLibs Include="$(MSBuildThisFileDirectory)**\*.dll" /> |
|
||||
<Content Include="@(PlatformLibs)"> |
|
||||
<Link>%(RecursiveDir)%(FileName)%(Extension)</Link> |
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
|
||||
</Content> |
|
||||
</ItemGroup> |
|
||||
</Project> |
|
||||
@ -0,0 +1,255 @@ |
|||||
|
// 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.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
|
||||
|
namespace Perspex |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Tracks registered <see cref="PerspexProperty"/> instances.
|
||||
|
/// </summary>
|
||||
|
public class PerspexPropertyRegistry |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The registered properties by type.
|
||||
|
/// </summary>
|
||||
|
private readonly Dictionary<Type, List<PerspexProperty>> _registered = |
||||
|
new Dictionary<Type, List<PerspexProperty>>(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The registered attached properties by owner type.
|
||||
|
/// </summary>
|
||||
|
private readonly Dictionary<Type, List<PerspexProperty>> _attached = |
||||
|
new Dictionary<Type, List<PerspexProperty>>(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the <see cref="PerspexPropertyRegistry"/> instance
|
||||
|
/// </summary>
|
||||
|
public static PerspexPropertyRegistry Instance { get; } |
||||
|
= new PerspexPropertyRegistry(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets all attached <see cref="PerspexProperty"/>s registered by an owner.
|
||||
|
/// </summary>
|
||||
|
/// <param name="ownerType">The owner type.</param>
|
||||
|
/// <returns>A collection of <see cref="PerspexProperty"/> definitions.</returns>
|
||||
|
public IEnumerable<PerspexProperty> GetAttached(Type ownerType) |
||||
|
{ |
||||
|
List<PerspexProperty> list; |
||||
|
|
||||
|
if (_attached.TryGetValue(ownerType, out list)) |
||||
|
{ |
||||
|
return list; |
||||
|
} |
||||
|
|
||||
|
return Enumerable.Empty<PerspexProperty>(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets all <see cref="PerspexProperty"/>s registered on a type.
|
||||
|
/// </summary>
|
||||
|
/// <param name="type">The type.</param>
|
||||
|
/// <returns>A collection of <see cref="PerspexProperty"/> definitions.</returns>
|
||||
|
public IEnumerable<PerspexProperty> GetRegistered(Type type) |
||||
|
{ |
||||
|
Contract.Requires<ArgumentNullException>(type != null); |
||||
|
|
||||
|
var i = type.GetTypeInfo(); |
||||
|
|
||||
|
while (type != null) |
||||
|
{ |
||||
|
List<PerspexProperty> list; |
||||
|
|
||||
|
if (_registered.TryGetValue(type, out list)) |
||||
|
{ |
||||
|
foreach (PerspexProperty p in list) |
||||
|
{ |
||||
|
yield return p; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
type = type.GetTypeInfo().BaseType; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets all <see cref="PerspexProperty"/>s registered on a object.
|
||||
|
/// </summary>
|
||||
|
/// <param name="o">The object.</param>
|
||||
|
/// <returns>A collection of <see cref="PerspexProperty"/> definitions.</returns>
|
||||
|
public IEnumerable<PerspexProperty> GetRegistered(PerspexObject o) |
||||
|
{ |
||||
|
Contract.Requires<ArgumentNullException>(o != null); |
||||
|
|
||||
|
return GetRegistered(o.GetType()); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Finds <see cref="PerspexProperty"/> registered on a type.
|
||||
|
/// </summary>
|
||||
|
/// <param name="type">The type.</param>
|
||||
|
/// <param name="property">The property.</param>
|
||||
|
/// <returns>The registered property or null if not found.</returns>
|
||||
|
/// <remarks>
|
||||
|
/// Calling AddOwner on a PerspexProperty creates a new PerspexProperty that is a
|
||||
|
/// different object but is equal according to <see cref="object.Equals(object)"/>.
|
||||
|
/// </remarks>
|
||||
|
public PerspexProperty FindRegistered(Type type, PerspexProperty property) |
||||
|
{ |
||||
|
while (type != null) |
||||
|
{ |
||||
|
List<PerspexProperty> list; |
||||
|
|
||||
|
if (_registered.TryGetValue(type, out list)) |
||||
|
{ |
||||
|
var index = list.IndexOf(property); |
||||
|
|
||||
|
if (index != -1) |
||||
|
{ |
||||
|
return list[index]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
type = type.GetTypeInfo().BaseType; |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Finds <see cref="PerspexProperty"/> registered on an object.
|
||||
|
/// </summary>
|
||||
|
/// <param name="o">The object.</param>
|
||||
|
/// <param name="property">The property.</param>
|
||||
|
/// <returns>The registered property or null if not found.</returns>
|
||||
|
/// <remarks>
|
||||
|
/// Calling AddOwner on a PerspexProperty creates a new PerspexProperty that is a
|
||||
|
/// different object but is equal according to <see cref="object.Equals(object)"/>.
|
||||
|
/// </remarks>
|
||||
|
public PerspexProperty FindRegistered(object o, PerspexProperty property) |
||||
|
{ |
||||
|
return FindRegistered(o.GetType(), property); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Finds a registered property on a type by name.
|
||||
|
/// </summary>
|
||||
|
/// <param name="type">The type.</param>
|
||||
|
/// <param name="name">
|
||||
|
/// The property name. If an attached property it should be in the form
|
||||
|
/// "OwnerType.PropertyName".
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The registered property or null if no matching property found.
|
||||
|
/// </returns>
|
||||
|
public PerspexProperty FindRegistered(Type type, string name) |
||||
|
{ |
||||
|
Contract.Requires<ArgumentNullException>(type != null); |
||||
|
Contract.Requires<ArgumentNullException>(name != null); |
||||
|
|
||||
|
var parts = name.Split('.'); |
||||
|
|
||||
|
if (parts.Length < 1 || parts.Length > 2) |
||||
|
{ |
||||
|
throw new ArgumentException("Invalid property name."); |
||||
|
} |
||||
|
|
||||
|
string propertyName; |
||||
|
var results = GetRegistered(type); |
||||
|
|
||||
|
if (parts.Length == 1) |
||||
|
{ |
||||
|
propertyName = parts[0]; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var types = GetImplementedTypes(type); |
||||
|
|
||||
|
if (!types.Contains(parts[0])) |
||||
|
{ |
||||
|
results = results.Where(x => x.OwnerType.Name == parts[0]); |
||||
|
} |
||||
|
|
||||
|
propertyName = parts[1]; |
||||
|
} |
||||
|
|
||||
|
return results.FirstOrDefault(x => x.Name == propertyName); |
||||
|
} |
||||
|
|
||||
|
private IEnumerable<string> GetImplementedTypes(Type type) |
||||
|
{ |
||||
|
while (type != null) |
||||
|
{ |
||||
|
yield return type.Name; |
||||
|
type = type.GetTypeInfo().BaseType; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Checks whether a <see cref="PerspexProperty"/> is registered on a type.
|
||||
|
/// </summary>
|
||||
|
/// <param name="type">The type.</param>
|
||||
|
/// <param name="property">The property.</param>
|
||||
|
/// <returns>True if the property is registered, otherwise false.</returns>
|
||||
|
public bool IsRegistered(Type type, PerspexProperty property) |
||||
|
{ |
||||
|
return FindRegistered(type, property) != null; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Checks whether a <see cref="PerspexProperty"/> is registered on a object.
|
||||
|
/// </summary>
|
||||
|
/// <param name="o">The object.</param>
|
||||
|
/// <param name="property">The property.</param>
|
||||
|
/// <returns>True if the property is registered, otherwise false.</returns>
|
||||
|
public bool IsRegistered(object o, PerspexProperty property) |
||||
|
{ |
||||
|
return IsRegistered(o.GetType(), property); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Registers a <see cref="PerspexProperty"/> on a type.
|
||||
|
/// </summary>
|
||||
|
/// <param name="type">The type.</param>
|
||||
|
/// <param name="property">The property.</param>
|
||||
|
/// <remarks>
|
||||
|
/// You won't usually want to call this method directly, instead use the
|
||||
|
/// <see cref="PerspexProperty.Register"/> method.
|
||||
|
/// </remarks>
|
||||
|
public void Register(Type type, PerspexProperty property) |
||||
|
{ |
||||
|
Contract.Requires<ArgumentNullException>(type != null); |
||||
|
Contract.Requires<ArgumentNullException>(property != null); |
||||
|
|
||||
|
List<PerspexProperty> list; |
||||
|
|
||||
|
if (!_registered.TryGetValue(type, out list)) |
||||
|
{ |
||||
|
list = new List<PerspexProperty>(); |
||||
|
_registered.Add(type, list); |
||||
|
} |
||||
|
|
||||
|
if (!list.Contains(property)) |
||||
|
{ |
||||
|
list.Add(property); |
||||
|
} |
||||
|
|
||||
|
if (property.IsAttached) |
||||
|
{ |
||||
|
if (!_attached.TryGetValue(property.OwnerType, out list)) |
||||
|
{ |
||||
|
list = new List<PerspexProperty>(); |
||||
|
_attached.Add(property.OwnerType, list); |
||||
|
} |
||||
|
|
||||
|
if (!list.Contains(property)) |
||||
|
{ |
||||
|
list.Add(property); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,177 @@ |
|||||
|
// 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.
|
||||
|
|
||||
|
using System.Linq; |
||||
|
using System.Reactive.Linq; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Perspex.Base.UnitTests |
||||
|
{ |
||||
|
public class PerspexPropertyRegistryTests |
||||
|
{ |
||||
|
public PerspexPropertyRegistryTests() |
||||
|
{ |
||||
|
// Ensure properties are registered.
|
||||
|
PerspexProperty p; |
||||
|
p = Class1.FooProperty; |
||||
|
p = Class2.BarProperty; |
||||
|
p = AttachedOwner.AttachedProperty; |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void GetRegistered_Returns_Registered_Properties() |
||||
|
{ |
||||
|
string[] names = PerspexPropertyRegistry.Instance.GetRegistered(typeof(Class1)) |
||||
|
.Select(x => x.Name) |
||||
|
.ToArray(); |
||||
|
|
||||
|
Assert.Equal(new[] { "Foo", "Baz", "Qux", "Attached" }, names); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void GetRegistered_Returns_Registered_Properties_For_Base_Types() |
||||
|
{ |
||||
|
string[] names = PerspexPropertyRegistry.Instance.GetRegistered(typeof(Class2)) |
||||
|
.Select(x => x.Name) |
||||
|
.ToArray(); |
||||
|
|
||||
|
Assert.Equal(new[] { "Bar", "Flob", "Fred", "Foo", "Baz", "Qux", "Attached" }, names); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void GetAttached_Returns_Registered_Properties_For_Base_Types() |
||||
|
{ |
||||
|
string[] names = PerspexPropertyRegistry.Instance.GetAttached(typeof(AttachedOwner)).Select(x => x.Name).ToArray(); |
||||
|
|
||||
|
Assert.Equal(new[] { "Attached" }, names); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void FindRegistered_Finds_Untyped_Property() |
||||
|
{ |
||||
|
var result = PerspexPropertyRegistry.Instance.FindRegistered(typeof(Class1), "Foo"); |
||||
|
|
||||
|
Assert.Equal(Class1.FooProperty, result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void FindRegistered_Finds_Typed_Property() |
||||
|
{ |
||||
|
var result = PerspexPropertyRegistry.Instance.FindRegistered(typeof(Class1), "Class1.Foo"); |
||||
|
|
||||
|
Assert.Equal(Class1.FooProperty, result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void FindRegistered_Finds_Typed_Inherited_Property() |
||||
|
{ |
||||
|
var result = PerspexPropertyRegistry.Instance.FindRegistered(typeof(Class2), "Class1.Foo"); |
||||
|
|
||||
|
Assert.Equal(Class2.FooProperty, result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void FindRegistered_Finds_Inherited_Property_With_Derived_Type_Name() |
||||
|
{ |
||||
|
var result = PerspexPropertyRegistry.Instance.FindRegistered(typeof(Class2), "Class2.Foo"); |
||||
|
|
||||
|
Assert.Equal(Class2.FooProperty, result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void FindRegistered_Finds_Attached_Property() |
||||
|
{ |
||||
|
var result = PerspexPropertyRegistry.Instance.FindRegistered(typeof(Class2), "AttachedOwner.Attached"); |
||||
|
|
||||
|
Assert.Equal(AttachedOwner.AttachedProperty, result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void FindRegistered_Finds_AddOwnered_Untyped_Attached_Property() |
||||
|
{ |
||||
|
var result = PerspexPropertyRegistry.Instance.FindRegistered(typeof(Class3), "Attached"); |
||||
|
|
||||
|
Assert.Equal(AttachedOwner.AttachedProperty, result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void FindRegistered_Finds_AddOwnered_Typed_Attached_Property() |
||||
|
{ |
||||
|
var result = PerspexPropertyRegistry.Instance.FindRegistered(typeof(Class3), "Class3.Attached"); |
||||
|
|
||||
|
Assert.Equal(AttachedOwner.AttachedProperty, result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void FindRegistered_Finds_AddOwnered_AttachedTyped_Attached_Property() |
||||
|
{ |
||||
|
var result = PerspexPropertyRegistry.Instance.FindRegistered(typeof(Class3), "AttachedOwner.Attached"); |
||||
|
|
||||
|
Assert.Equal(AttachedOwner.AttachedProperty, result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void FindRegistered_Finds_AddOwnered_BaseTyped_Attached_Property() |
||||
|
{ |
||||
|
var result = PerspexPropertyRegistry.Instance.FindRegistered(typeof(Class3), "Class1.Attached"); |
||||
|
|
||||
|
Assert.Equal(AttachedOwner.AttachedProperty, result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void FindRegistered_Doesnt_Find_Nonregistered_Property() |
||||
|
{ |
||||
|
var result = PerspexPropertyRegistry.Instance.FindRegistered(typeof(Class1), "Bar"); |
||||
|
|
||||
|
Assert.Null(result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void FindRegistered_Doesnt_Find_Nonregistered_Attached_Property() |
||||
|
{ |
||||
|
var result = PerspexPropertyRegistry.Instance.FindRegistered(typeof(Class4), "AttachedOwner.Attached"); |
||||
|
|
||||
|
Assert.Null(result); |
||||
|
} |
||||
|
|
||||
|
private class Class1 : PerspexObject |
||||
|
{ |
||||
|
public static readonly PerspexProperty<string> FooProperty = |
||||
|
PerspexProperty.Register<Class1, string>("Foo"); |
||||
|
|
||||
|
public static readonly PerspexProperty<string> BazProperty = |
||||
|
PerspexProperty.Register<Class1, string>("Baz"); |
||||
|
|
||||
|
public static readonly PerspexProperty<int> QuxProperty = |
||||
|
PerspexProperty.Register<Class1, int>("Qux"); |
||||
|
} |
||||
|
|
||||
|
private class Class2 : Class1 |
||||
|
{ |
||||
|
public static readonly PerspexProperty<string> BarProperty = |
||||
|
PerspexProperty.Register<Class2, string>("Bar"); |
||||
|
|
||||
|
public static readonly PerspexProperty<double> FlobProperty = |
||||
|
PerspexProperty.Register<Class2, double>("Flob"); |
||||
|
|
||||
|
public static readonly PerspexProperty<double?> FredProperty = |
||||
|
PerspexProperty.Register<Class2, double?>("Fred"); |
||||
|
} |
||||
|
|
||||
|
private class Class3 : Class1 |
||||
|
{ |
||||
|
public static readonly PerspexProperty<string> AttachedProperty = |
||||
|
AttachedOwner.AttachedProperty.AddOwner<Class3>(); |
||||
|
} |
||||
|
|
||||
|
public class Class4 : PerspexObject |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
private class AttachedOwner |
||||
|
{ |
||||
|
public static readonly PerspexProperty<string> AttachedProperty = |
||||
|
PerspexProperty.RegisterAttached<AttachedOwner, Class1, string>("Attached"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,93 @@ |
|||||
|
// 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.
|
||||
|
|
||||
|
using System.Linq; |
||||
|
using Perspex.Controls.Generators; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Perspex.Controls.UnitTests.Generators |
||||
|
{ |
||||
|
public class ItemContainerGeneratorTests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void Materialize_Should_Create_Containers() |
||||
|
{ |
||||
|
var items = new[] { "foo", "bar", "baz" }; |
||||
|
var owner = new Decorator(); |
||||
|
var target = new ItemContainerGenerator(owner); |
||||
|
var containers = target.Materialize(0, items, null); |
||||
|
var result = containers.OfType<TextBlock>().Select(x => x.Text).ToList(); |
||||
|
|
||||
|
Assert.Equal(items, result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void ContainerFromIndex_Should_Return_Materialized_Containers() |
||||
|
{ |
||||
|
var items = new[] { "foo", "bar", "baz" }; |
||||
|
var owner = new Decorator(); |
||||
|
var target = new ItemContainerGenerator(owner); |
||||
|
var containers = target.Materialize(0, items, null).ToList(); |
||||
|
|
||||
|
Assert.Equal(containers[0], target.ContainerFromIndex(0)); |
||||
|
Assert.Equal(containers[1], target.ContainerFromIndex(1)); |
||||
|
Assert.Equal(containers[2], target.ContainerFromIndex(2)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void IndexFromContainer_Should_Return_Index() |
||||
|
{ |
||||
|
var items = new[] { "foo", "bar", "baz" }; |
||||
|
var owner = new Decorator(); |
||||
|
var target = new ItemContainerGenerator(owner); |
||||
|
var containers = target.Materialize(0, items, null).ToList(); |
||||
|
|
||||
|
Assert.Equal(0, target.IndexFromContainer(containers[0])); |
||||
|
Assert.Equal(1, target.IndexFromContainer(containers[1])); |
||||
|
Assert.Equal(2, target.IndexFromContainer(containers[2])); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Dematerialize_Should_Remove_Container() |
||||
|
{ |
||||
|
var items = new[] { "foo", "bar", "baz" }; |
||||
|
var owner = new Decorator(); |
||||
|
var target = new ItemContainerGenerator(owner); |
||||
|
var containers = target.Materialize(0, items, null).ToList(); |
||||
|
|
||||
|
target.Dematerialize(1, 1); |
||||
|
|
||||
|
Assert.Equal(containers[0], target.ContainerFromIndex(0)); |
||||
|
Assert.Equal(null, target.ContainerFromIndex(1)); |
||||
|
Assert.Equal(containers[2], target.ContainerFromIndex(2)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Dematerialize_Should_Return_Removed_Containers() |
||||
|
{ |
||||
|
var items = new[] { "foo", "bar", "baz" }; |
||||
|
var owner = new Decorator(); |
||||
|
var target = new ItemContainerGenerator(owner); |
||||
|
var containers = target.Materialize(0, items, null); |
||||
|
var expected = target.Containers.Take(2).ToList(); |
||||
|
var result = target.Dematerialize(0, 2); |
||||
|
|
||||
|
Assert.Equal(expected, result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void RemoveRange_Should_Alter_Successive_Container_Indexes() |
||||
|
{ |
||||
|
var items = new[] { "foo", "bar", "baz" }; |
||||
|
var owner = new Decorator(); |
||||
|
var target = new ItemContainerGenerator(owner); |
||||
|
var containers = target.Materialize(0, items, null).ToList(); |
||||
|
|
||||
|
var removed = target.RemoveRange(1, 1).Single(); |
||||
|
|
||||
|
Assert.Equal(containers[0], target.ContainerFromIndex(0)); |
||||
|
Assert.Equal(containers[2], target.ContainerFromIndex(1)); |
||||
|
Assert.Equal(containers[1], removed); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,28 @@ |
|||||
|
// 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.
|
||||
|
|
||||
|
using System.Linq; |
||||
|
using Perspex.Controls.Generators; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Perspex.Controls.UnitTests.Generators |
||||
|
{ |
||||
|
public class ItemContainerGeneratorTypedTests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void Materialize_Should_Create_Containers() |
||||
|
{ |
||||
|
var items = new[] { "foo", "bar", "baz" }; |
||||
|
var owner = new Decorator(); |
||||
|
var target = new ItemContainerGenerator<ListBoxItem>(owner, ListBoxItem.ContentProperty); |
||||
|
var containers = target.Materialize(0, items, null); |
||||
|
var result = containers |
||||
|
.OfType<ListBoxItem>() |
||||
|
.Select(x => x.Content) |
||||
|
.OfType<TextBlock>() |
||||
|
.Select(x => x.Text).ToList(); |
||||
|
|
||||
|
Assert.Equal(items, result); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue