diff --git a/src/Perspex.Base/PerspexProperty.cs b/src/Perspex.Base/PerspexProperty.cs
index 62a3d5cfe2..2dd679ce8d 100644
--- a/src/Perspex.Base/PerspexProperty.cs
+++ b/src/Perspex.Base/PerspexProperty.cs
@@ -29,7 +29,12 @@ namespace Perspex
private static int s_nextId = 1;
///
- /// The default values for the property, by type.
+ /// The default value provided when the property was first registered.
+ ///
+ private readonly object _defaultValue;
+
+ ///
+ /// The overridden default values for the property, by type.
///
private readonly Dictionary _defaultValues = new Dictionary();
@@ -93,7 +98,7 @@ namespace Perspex
Name = name;
PropertyType = valueType;
OwnerType = ownerType;
- _defaultValues.Add(ownerType, defaultValue);
+ _defaultValue = defaultValue;
Inherits = inherits;
DefaultBindingMode = defaultBindingMode;
IsAttached = isAttached;
@@ -144,14 +149,57 @@ namespace Perspex
/// Initializes a new instance of the class.
///
/// The direct property to copy.
+ /// The new owner type.
+ protected PerspexProperty(PerspexProperty source, Type ownerType)
+ {
+ Contract.Requires(source != null);
+ Contract.Requires(ownerType != null);
+
+ if (source.IsDirect)
+ {
+ throw new InvalidOperationException(
+ "This method cannot be called on direct PerspexProperties.");
+ }
+
+ //Name = name;
+ //PropertyType = valueType;
+ //OwnerType = ownerType;
+ //_defaultValues.Add(ownerType, defaultValue);
+ //Inherits = inherits;
+ //DefaultBindingMode = defaultBindingMode;
+ //IsAttached = isAttached;
+ //Notifying = notifying;
+ //_id = s_nextId++;
+
+
+ Name = source.Name;
+ PropertyType = source.PropertyType;
+ OwnerType = ownerType;
+ _defaultValue = source._defaultValue;
+ _defaultValues = source._defaultValues;
+ Inherits = source.Inherits;
+ DefaultBindingMode = source.DefaultBindingMode;
+ IsAttached = false;
+ Notifying = Notifying;
+ _validation = source._validation;
+ _id = source._id;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The direct property to copy.
+ /// The new owner type.
/// A new getter.
/// A new setter.
protected PerspexProperty(
PerspexProperty source,
+ Type ownerType,
Func getter,
Action setter)
{
Contract.Requires(source != null);
+ Contract.Requires(ownerType != null);
Contract.Requires(getter != null);
if (!source.IsDirect)
@@ -162,7 +210,7 @@ namespace Perspex
Name = source.Name;
PropertyType = source.PropertyType;
- OwnerType = source.OwnerType;
+ OwnerType = ownerType;
Getter = getter;
Setter = setter;
IsDirect = true;
@@ -530,7 +578,7 @@ namespace Perspex
type = type.GetTypeInfo().BaseType;
}
- return _defaultValues[OwnerType];
+ return _defaultValue;
}
///
diff --git a/src/Perspex.Base/PerspexProperty`1.cs b/src/Perspex.Base/PerspexProperty`1.cs
index 9a39b95c0c..6d97833f0a 100644
--- a/src/Perspex.Base/PerspexProperty`1.cs
+++ b/src/Perspex.Base/PerspexProperty`1.cs
@@ -66,17 +66,29 @@ namespace Perspex
Setter = setter;
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The property to copy.
+ /// The new owner type.
+ private PerspexProperty(PerspexProperty source, Type ownerType)
+ : base(source, ownerType)
+ {
+ }
+
///
/// Initializes a new instance of the class.
///
/// The direct property to copy.
+ /// The new owner type.
/// A new getter.
/// A new setter.
private PerspexProperty(
PerspexProperty source,
+ Type ownerType,
Func getter,
Action setter)
- : base(source, CastParamReturn(getter), CastParams(setter))
+ : base(source, ownerType, CastParamReturn(getter), CastParams(setter))
{
Getter = getter;
Setter = setter;
@@ -105,8 +117,9 @@ namespace Perspex
"You must provide a new getter and setter when calling AddOwner on a direct PerspexProperty.");
}
- PerspexPropertyRegistry.Instance.Register(typeof(TOwner), this);
- return this;
+ var result = new PerspexProperty(this, typeof(TOwner));
+ PerspexPropertyRegistry.Instance.Register(typeof(TOwner), result);
+ return result;
}
///
@@ -119,8 +132,15 @@ namespace Perspex
Action setter = null)
where TOwner : PerspexObject
{
+ if (!IsDirect)
+ {
+ throw new InvalidOperationException(
+ "This overload of AddOwner is for direct PerspexProperties.");
+ }
+
var result = new PerspexProperty(
- this,
+ this,
+ typeof(TOwner),
CastReturn(getter),
CastParam1(setter));
diff --git a/tests/Perspex.Base.UnitTests/PerspexPropertyTests.cs b/tests/Perspex.Base.UnitTests/PerspexPropertyTests.cs
index 6c90ac1039..c858152da5 100644
--- a/tests/Perspex.Base.UnitTests/PerspexPropertyTests.cs
+++ b/tests/Perspex.Base.UnitTests/PerspexPropertyTests.cs
@@ -161,6 +161,15 @@ namespace Perspex.Base.UnitTests
Assert.True(p1 == p2);
}
+ [Fact]
+ public void AddOwnered_Property_Should_Have_OwnerType_Set()
+ {
+ var p1 = new PerspexProperty("p1", typeof(Class1));
+ var p2 = p1.AddOwner();
+
+ Assert.Equal(typeof(Class3), p2.OwnerType);
+ }
+
[Fact]
public void AddOwnered_Direct_Property_Should_Equal_Original()
{
@@ -172,6 +181,15 @@ namespace Perspex.Base.UnitTests
Assert.True(p1 == p2);
}
+ [Fact]
+ public void AddOwnered_Direct_Property_Should_Have_OwnerType_Set()
+ {
+ var p1 = new PerspexProperty("d1", typeof(Class1), o => null, (o, v) => { });
+ var p2 = p1.AddOwner(o => null, (o, v) => { });
+
+ Assert.Equal(typeof(Class3), p2.OwnerType);
+ }
+
[Fact]
public void AddOwner_With_Getter_And_Setter_On_Standard_Property_Should_Throw()
{