// ----------------------------------------------------------------------- // // Copyright 2014 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- namespace Perspex { using System; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; /// /// A perspex property. /// /// /// This class is analogous to DependencyProperty in WPF. /// public class PerspexProperty { /// /// The default values for the property, by type. /// private Dictionary defaultValues = new Dictionary(); /// /// Initializes a new instance of the class. /// /// The name of the property. /// The type of the property's value. /// The type of the class that registers the property. /// The default value of the property. /// Whether the property inherits its value. public PerspexProperty( string name, Type valueType, Type ownerType, object defaultValue, bool inherits) { Contract.Requires(name != null); Contract.Requires(valueType != null); Contract.Requires(ownerType != null); this.Name = name; this.PropertyType = valueType; this.OwnerType = ownerType; this.Inherits = inherits; this.defaultValues.Add(ownerType, defaultValue); } /// /// Gets the name of the property. /// public string Name { get; private set; } /// /// Gets the type of the property's value. /// public Type PropertyType { get; private set; } /// /// Gets the type of the class that registers the property. /// public Type OwnerType { get; private set; } /// /// Gets a value indicating whether the property inherits its value. /// public bool Inherits { get; private set; } /// /// Registers a . /// /// The type of the class that is registering the property. /// The type of the property's value. /// The name of the property. /// The default value of the property. /// Whether the property inherits its value. /// public static PerspexProperty Register( string name, TValue defaultValue = default(TValue), bool inherits = false) where TOwner : PerspexObject { Contract.Requires(name != null); PerspexProperty result = new PerspexProperty( name, typeof(TOwner), defaultValue, inherits); PerspexObject.Register(typeof(TOwner), result); return result; } /// /// Gets the default value for the property on the specified type. /// /// The type. /// The default value. public object GetDefaultValue(Type type) { Contract.Requires(type != null); while (type != null) { object result; if (this.defaultValues.TryGetValue(type, out result)) { return result; } type = type.GetTypeInfo().BaseType; } return this.defaultValues[this.OwnerType]; } public bool IsValidType(object value) { if (value == null) { return !this.PropertyType.GetTypeInfo().IsValueType || Nullable.GetUnderlyingType(this.PropertyType) != null; } return this.PropertyType.GetTypeInfo().IsAssignableFrom(value.GetType().GetTypeInfo()); } /// /// Gets the default value for the property on the specified type. /// /// The type. /// The default value. public void OverrideDefaultValue(Type type, object defaultValue) { Contract.Requires(type != null); // TODO: Ensure correct type. if (this.defaultValues.ContainsKey(type)) { throw new InvalidOperationException("Default value is already set for this property."); } this.defaultValues.Add(type, defaultValue); } } /// /// A typed perspex property. /// public class PerspexProperty : PerspexProperty { /// /// Initializes a new instance of the class. /// /// The name of the property. /// The type of the class that registers the property. /// The default value of the property. /// Whether the property inherits its value. public PerspexProperty( string name, Type ownerType, TValue defaultValue, bool inherits) : base(name, typeof(TValue), ownerType, defaultValue, inherits) { Contract.Requires(name != null); Contract.Requires(ownerType != null); } /// /// Registers the property on another type. /// /// The type of the additional owner. /// The property. public PerspexProperty AddOwner() { PerspexObject.Register(typeof(TOwner), this); return this; } /// /// Gets the default value for the property on the specified type. /// /// The type. /// The default value. public TValue GetDefaultValue() { return (TValue)this.GetDefaultValue(typeof(T)); } } }