2 using System.Collections.Generic;
3 using System.Diagnostics;
4 using System.Linq.Expressions;
5 using System.Reflection;
6 using System.ComponentModel;
7 using Tizen.NUI.Binding.Internals;
10 namespace Tizen.NUI.Binding
13 /// A BindableProperty is a backing store for properties allowing bindings on BindableObject.
15 [DebuggerDisplay("{PropertyName}")]
16 [TypeConverter(typeof(BindablePropertyConverter))]
17 [EditorBrowsable(EditorBrowsableState.Never)]
18 public sealed class BindableProperty
21 /// Delegate for BindableProperty.PropertyChanged.
23 /// <param name="bindable">The bindable object that contains the property.</param>
24 /// <param name="oldValue">The old property value.</param>
25 /// <param name="newValue">The new property value.</param>
26 public delegate void BindingPropertyChangedDelegate(BindableObject bindable, object oldValue, object newValue);
29 /// Strongly-typed delegate for BindableProperty.PropertyChanged.
31 /// <typeparam name="TPropertyType">The type of the bound property.</typeparam>
32 /// <param name="bindable">The bindable object that contains the property.</param>
33 /// <param name="oldValue">The old property value.</param>
34 /// <param name="newValue">The new property value.</param>
35 public delegate void BindingPropertyChangedDelegate<in TPropertyType>(BindableObject bindable, TPropertyType oldValue, TPropertyType newValue);
38 /// Delegate for BindableProperty.PropertyChanging.
40 /// <param name="bindable">The bindable object that contains the property.</param>
41 /// <param name="oldValue">The old property value.</param>
42 /// <param name="newValue">The new property value.</param>
43 public delegate void BindingPropertyChangingDelegate(BindableObject bindable, object oldValue, object newValue);
46 /// Strongly-typed delegate for BindableProperty.PropertyChanging.
48 /// <typeparam name="TPropertyType">The type of the bound property.</typeparam>
49 /// <param name="bindable">The bindable object that contains the property.</param>
50 /// <param name="oldValue">The old property value.</param>
51 /// <param name="newValue">The new property value.</param>
52 public delegate void BindingPropertyChangingDelegate<in TPropertyType>(BindableObject bindable, TPropertyType oldValue, TPropertyType newValue);
55 /// Delegate for BindableProperty.CoerceValue.
57 /// <param name="bindable">The bindable object that contains the property.</param>
58 /// <param name="value">The value to coerce.</param>
59 /// <returns>System.Object</returns>
60 public delegate object CoerceValueDelegate(BindableObject bindable, object value);
63 /// Strongly-typed delegate for BindableProperty.CoerceValue.
65 /// <typeparam name="TPropertyType">The type of the bound property.</typeparam>
66 /// <param name="bindable">The bindable object that contains the property.</param>
67 /// <param name="value">The value to coerce.</param>
68 /// <returns>TPropertyType</returns>
69 public delegate TPropertyType CoerceValueDelegate<TPropertyType>(BindableObject bindable, TPropertyType value);
72 /// Delegate for BindableProperty.DefaultValueCreator.
74 /// <param name="bindable">The bindable object that contains the property.</param>
75 /// <returns>System.Object</returns>
76 public delegate object CreateDefaultValueDelegate(BindableObject bindable);
79 /// Strongly-typed delegate for BindableProperty.DefaultValueCreator.
81 /// <typeparam name="TDeclarer">The type of the object that delared the property.</typeparam>
82 /// <typeparam name="TPropertyType">The type of the bound property.</typeparam>
83 /// <param name="bindable">The bindable object that contains the property.</param>
84 /// <returns>TPropertyType</returns>
85 public delegate TPropertyType CreateDefaultValueDelegate<in TDeclarer, out TPropertyType>(TDeclarer bindable);
88 /// Delegate for BindableProperty.ValidateValue.
90 /// <param name="bindable">The bindable object that contains the property.</param>
91 /// <param name="value">The default value.</param>
92 /// <returns>System.Boolean</returns>
93 public delegate bool ValidateValueDelegate(BindableObject bindable, object value);
96 /// Strongly-typed delegate for BindableProperty.ValidateValue.
98 /// <typeparam name="TPropertyType">The type of the bound property.</typeparam>
99 /// <param name="bindable">The bindable object that contains the property.</param>
100 /// <param name="value">The default value.</param>
101 /// <returns>System.Boolean</returns>
102 public delegate bool ValidateValueDelegate<in TPropertyType>(BindableObject bindable, TPropertyType value);
104 static readonly Dictionary<Type, TypeConverter> WellKnownConvertTypes = new Dictionary<Type,TypeConverter>
106 { typeof(Uri), new UriTypeConverter() },
107 { typeof(Color), new ColorTypeConverter() },
108 { typeof(Size2D), new Size2DTypeConverter() },
109 { typeof(Position2D), new Position2DTypeConverter() },
110 { typeof(Size), new SizeTypeConverter() },
111 { typeof(Position), new PositionTypeConverter() },
112 { typeof(Rectangle), new RectangleTypeConverter() },
113 { typeof(Rotation), new RotationTypeConverter() },
114 { typeof(Thickness), new ThicknessTypeConverter() },
115 { typeof(Vector2), new Vector2TypeConverter() },
116 { typeof(Vector3), new Vector3TypeConverter() },
117 { typeof(Vector4), new Vector4TypeConverter() },
118 { typeof(RelativeVector2), new RelativeVector2TypeConverter() },
119 { typeof(RelativeVector3), new RelativeVector3TypeConverter() },
120 { typeof(RelativeVector4), new RelativeVector4TypeConverter() },
123 //Modification for NUI XAML : user defined converter for DynamicResource can be added
124 static internal Dictionary<Type, TypeConverter> UserCustomConvertTypes = new Dictionary<Type, TypeConverter>
128 // more or less the encoding of this, without the need to reflect
129 // http://msdn.microsoft.com/en-us/library/y5b434w4.aspx
130 static readonly Dictionary<Type, Type[]> SimpleConvertTypes = new Dictionary<Type, Type[]>
132 { typeof(sbyte), new[] { typeof(string), typeof(short), typeof(int), typeof(long), typeof(float), typeof(double), typeof(decimal) } },
133 { typeof(byte), new[] { typeof(string), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(ulong), typeof(float), typeof(double), typeof(decimal) } },
134 { typeof(short), new[] { typeof(string), typeof(int), typeof(long), typeof(float), typeof(double), typeof(decimal) } },
135 { typeof(ushort), new[] { typeof(string), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal) } },
136 { typeof(int), new[] { typeof(string), typeof(long), typeof(float), typeof(double), typeof(decimal) } },
137 { typeof(uint), new[] { typeof(string), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal) } },
138 { typeof(long), new[] { typeof(string), typeof(float), typeof(double), typeof(decimal) } },
139 { typeof(char), new[] { typeof(string), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal) } },
140 { typeof(float), new[] { typeof(string), typeof(double) } },
141 { typeof(ulong), new[] { typeof(string), typeof(float), typeof(double), typeof(decimal) } }
144 BindableProperty(string propertyName, Type returnType, Type declaringType, object defaultValue, BindingMode defaultBindingMode = BindingMode.OneWay,
145 ValidateValueDelegate validateValue = null, BindingPropertyChangedDelegate propertyChanged = null, BindingPropertyChangingDelegate propertyChanging = null,
146 CoerceValueDelegate coerceValue = null, BindablePropertyBindingChanging bindingChanging = null, bool isReadOnly = false, CreateDefaultValueDelegate defaultValueCreator = null)
148 if (propertyName == null)
149 throw new ArgumentNullException("propertyName");
150 if (ReferenceEquals(returnType, null))
151 throw new ArgumentNullException("returnType");
152 if (ReferenceEquals(declaringType, null))
153 throw new ArgumentNullException("declaringType");
155 // don't use Enum.IsDefined as its redonkulously expensive for what it does
156 if (defaultBindingMode != BindingMode.Default && defaultBindingMode != BindingMode.OneWay && defaultBindingMode != BindingMode.OneWayToSource && defaultBindingMode != BindingMode.TwoWay && defaultBindingMode != BindingMode.OneTime)
157 throw new ArgumentException("Not a valid type of BindingMode", "defaultBindingMode");
158 if (defaultValue == null && Nullable.GetUnderlyingType(returnType) == null && returnType.GetTypeInfo().IsValueType)
159 throw new ArgumentException("Not a valid default value", "defaultValue");
160 if (defaultValue != null && !returnType.IsInstanceOfType(defaultValue))
161 throw new ArgumentException("Default value did not match return type", "defaultValue");
162 if (defaultBindingMode == BindingMode.Default)
163 defaultBindingMode = BindingMode.OneWay;
165 PropertyName = propertyName;
166 ReturnType = returnType;
167 ReturnTypeInfo = returnType.GetTypeInfo();
168 DeclaringType = declaringType;
169 DefaultValue = defaultValue;
170 DefaultBindingMode = defaultBindingMode;
171 PropertyChanged = propertyChanged;
172 PropertyChanging = propertyChanging;
173 ValidateValue = validateValue;
174 CoerceValue = coerceValue;
175 BindingChanging = bindingChanging;
176 IsReadOnly = isReadOnly;
177 DefaultValueCreator = defaultValueCreator;
181 /// Gets the type declaring the BindableProperty.
183 public Type DeclaringType { get; private set; }
186 /// Gets the default BindingMode.
188 public BindingMode DefaultBindingMode { get; private set; }
191 /// Gets the default value for the BindableProperty.
193 public object DefaultValue { get; }
196 /// Gets a value indicating if the BindableProperty is created form a BindablePropertyKey.
198 public bool IsReadOnly { get; private set; }
201 /// Gets the property name.
203 public string PropertyName { get; }
206 /// Gets the type of the BindableProperty.
208 public Type ReturnType { get; }
210 internal BindablePropertyBindingChanging BindingChanging { get; private set; }
212 internal CoerceValueDelegate CoerceValue { get; private set; }
214 internal CreateDefaultValueDelegate DefaultValueCreator { get; }
216 internal BindingPropertyChangedDelegate PropertyChanged { get; private set; }
218 internal BindingPropertyChangingDelegate PropertyChanging { get; private set; }
220 internal System.Reflection.TypeInfo ReturnTypeInfo { get; }
222 internal ValidateValueDelegate ValidateValue { get; private set; }
225 /// Deprecated. Do not use.
227 /// <typeparam name="TDeclarer">The type of the declaring object.</typeparam>
228 /// <typeparam name="TPropertyType">The type of the property.</typeparam>
229 /// <param name="getter">An expression identifying the getter for the property using this BindableProperty as backing store.</param>
230 /// <param name="defaultValue">The default value for the property.</param>
231 /// <param name="defaultBindingMode">The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay.</param>
232 /// <param name="validateValue">A delegate to be run when a value is set. This parameter is optional. Default is null.</param>
233 /// <param name="propertyChanged">A delegate to be run when the value has changed. This parameter is optional. Default is null.</param>
234 /// <param name="propertyChanging">A delegate to be run when the value will change. This parameter is optional. Default is null.</param>
235 /// <param name="coerceValue">A delegate used to coerce the range of a value. This parameter is optional. Default is null.</param>
236 /// <param name="defaultValueCreator">A Func used to initialize default value for reference types.</param>
237 /// <returns>A newly created BindableProperty.</returns>
238 [Obsolete("Create<> (generic) is obsolete as of version 2.1.0 and is no longer supported.")]
239 public static BindableProperty Create<TDeclarer, TPropertyType>(Expression<Func<TDeclarer, TPropertyType>> getter, TPropertyType defaultValue, BindingMode defaultBindingMode = BindingMode.OneWay,
240 ValidateValueDelegate<TPropertyType> validateValue = null, BindingPropertyChangedDelegate<TPropertyType> propertyChanged = null,
241 BindingPropertyChangingDelegate<TPropertyType> propertyChanging = null, CoerceValueDelegate<TPropertyType> coerceValue = null,
242 CreateDefaultValueDelegate<TDeclarer, TPropertyType> defaultValueCreator = null) where TDeclarer : BindableObject
244 return Create(getter, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, null, defaultValueCreator: defaultValueCreator);
248 /// Creates a new instance of the BindableProperty class.
250 /// <param name="propertyName">The name of the BindableProperty.</param>
251 /// <param name="returnType">The type of the property.</param>
252 /// <param name="declaringType">The type of the declaring object.</param>
253 /// <param name="defaultValue">The default value for the property.</param>
254 /// <param name="defaultBindingMode">The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay.</param>
255 /// <param name="validateValue">A delegate to be run when a value is set. This parameter is optional. Default is null.</param>
256 /// <param name="propertyChanged">A delegate to be run when the value has changed. This parameter is optional. Default is null.</param>
257 /// <param name="propertyChanging">A delegate to be run when the value will change. This parameter is optional. Default is null.</param>
258 /// <param name="coerceValue">A delegate used to coerce the range of a value. This parameter is optional. Default is null.</param>
259 /// <param name="defaultValueCreator">A Func used to initialize default value for reference types.</param>
260 /// <returns>A newly created BindableProperty.</returns>
261 public static BindableProperty Create(string propertyName, Type returnType, Type declaringType, object defaultValue = null, BindingMode defaultBindingMode = BindingMode.OneWay,
262 ValidateValueDelegate validateValue = null, BindingPropertyChangedDelegate propertyChanged = null, BindingPropertyChangingDelegate propertyChanging = null,
263 CoerceValueDelegate coerceValue = null, CreateDefaultValueDelegate defaultValueCreator = null)
265 return new BindableProperty(propertyName, returnType, declaringType, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue,
266 defaultValueCreator: defaultValueCreator);
270 /// Deprecated. Do not use.
272 /// <typeparam name="TDeclarer">The type of the declaring object.</typeparam>
273 /// <typeparam name="TPropertyType">The type of the property.</typeparam>
274 /// <param name="staticgetter">An expression identifying a static method returning the value of the property using this BindableProperty as backing store.</param>
275 /// <param name="defaultValue">The default value for the property.</param>
276 /// <param name="defaultBindingMode">The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay.</param>
277 /// <param name="validateValue">A delegate to be run when a value is set. This parameter is optional. Default is null.</param>
278 /// <param name="propertyChanged">A delegate to be run when the value has changed. This parameter is optional. Default is null.</param>
279 /// <param name="propertyChanging">A delegate to be run when the value will change. This parameter is optional. Default is null.</param>
280 /// <param name="coerceValue">A delegate used to coerce the range of a value. This parameter is optional. Default is null.</param>
281 /// <param name="defaultValueCreator">A Func used to initialize default value for reference types.</param>
282 [Obsolete("CreateAttached<> (generic) is obsolete as of version 2.1.0 and is no longer supported.")]
283 public static BindableProperty CreateAttached<TDeclarer, TPropertyType>(Expression<Func<BindableObject, TPropertyType>> staticgetter, TPropertyType defaultValue,
284 BindingMode defaultBindingMode = BindingMode.OneWay, ValidateValueDelegate<TPropertyType> validateValue = null, BindingPropertyChangedDelegate<TPropertyType> propertyChanged = null,
285 BindingPropertyChangingDelegate<TPropertyType> propertyChanging = null, CoerceValueDelegate<TPropertyType> coerceValue = null,
286 CreateDefaultValueDelegate<BindableObject, TPropertyType> defaultValueCreator = null)
288 return CreateAttached<TDeclarer, TPropertyType>(staticgetter, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, null,
289 defaultValueCreator: defaultValueCreator);
293 /// Creates a new instance of the BindableProperty class for an attached property.
295 /// <param name="propertyName">The name of the BindableProperty.</param>
296 /// <param name="returnType">The type of the property.</param>
297 /// <param name="declaringType">The type of the declaring object.</param>
298 /// <param name="defaultValue">The default value for the property.</param>
299 /// <param name="defaultBindingMode">The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay.</param>
300 /// <param name="validateValue">A delegate to be run when a value is set. This parameter is optional. Default is null.</param>
301 /// <param name="propertyChanged">A delegate to be run when the value has changed. This parameter is optional. Default is null.</param>
302 /// <param name="propertyChanging">A delegate to be run when the value will change. This parameter is optional. Default is null.</param>
303 /// <param name="coerceValue">A delegate used to coerce the range of a value. This parameter is optional. Default is null.</param>
304 /// <param name="defaultValueCreator">A Func used to initialize default value for reference types.</param>
305 /// <returns>A newly created BindableProperty.</returns>
306 public static BindableProperty CreateAttached(string propertyName, Type returnType, Type declaringType, object defaultValue, BindingMode defaultBindingMode = BindingMode.OneWay,
307 ValidateValueDelegate validateValue = null, BindingPropertyChangedDelegate propertyChanged = null, BindingPropertyChangingDelegate propertyChanging = null,
308 CoerceValueDelegate coerceValue = null, CreateDefaultValueDelegate defaultValueCreator = null)
310 return CreateAttached(propertyName, returnType, declaringType, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, null, false, defaultValueCreator);
314 /// Deprecated. Do not use.
316 /// <typeparam name="TDeclarer">The type of the declaring object.</typeparam>
317 /// <typeparam name="TPropertyType">The type of the property.</typeparam>
318 /// <param name="staticgetter">An expression identifying a static method returning the value of the property using this BindableProperty as backing store.</param>
319 /// <param name="defaultValue">The default value for the property.</param>
320 /// <param name="defaultBindingMode">The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay.</param>
321 /// <param name="validateValue">A delegate to be run when a value is set. This parameter is optional. Default is null.</param>
322 /// <param name="propertyChanged">A delegate to be run when the value has changed. This parameter is optional. Default is null.</param>
323 /// <param name="propertyChanging">A delegate to be run when the value will change. This parameter is optional. Default is null.</param>
324 /// <param name="coerceValue">A delegate used to coerce the range of a value. This parameter is optional. Default is null.</param>
325 /// <param name="defaultValueCreator">A Func used to initialize default value for reference types.</param>
326 /// <returns>A newly created attached read-only BindablePropertyKey.</returns>
327 [Obsolete("CreateAttachedReadOnly<> (generic) is obsolete as of version 2.1.0 and is no longer supported.")]
328 public static BindablePropertyKey CreateAttachedReadOnly<TDeclarer, TPropertyType>(Expression<Func<BindableObject, TPropertyType>> staticgetter, TPropertyType defaultValue,
329 BindingMode defaultBindingMode = BindingMode.OneWayToSource, ValidateValueDelegate<TPropertyType> validateValue = null,
330 BindingPropertyChangedDelegate<TPropertyType> propertyChanged = null, BindingPropertyChangingDelegate<TPropertyType> propertyChanging = null,
331 CoerceValueDelegate<TPropertyType> coerceValue = null, CreateDefaultValueDelegate<BindableObject, TPropertyType> defaultValueCreator = null)
335 new BindablePropertyKey(CreateAttached<TDeclarer, TPropertyType>(staticgetter, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, null, true,
336 defaultValueCreator));
340 /// Creates a new instance of the BindableProperty class for attached read-only properties.
342 /// <param name="propertyName">The name of the BindableProperty.</param>
343 /// <param name="returnType">The type of the property.</param>
344 /// <param name="declaringType">The type of the declaring object.</param>
345 /// <param name="defaultValue">The default value for the property.</param>
346 /// <param name="defaultBindingMode">The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay.</param>
347 /// <param name="validateValue">A delegate to be run when a value is set. This parameter is optional. Default is null.</param>
348 /// <param name="propertyChanged">A delegate to be run when the value has changed. This parameter is optional. Default is null.</param>
349 /// <param name="propertyChanging">A delegate to be run when the value will change. This parameter is optional. Default is null.</param>
350 /// <param name="coerceValue">A delegate used to coerce the range of a value. This parameter is optional. Default is null.</param>
351 /// <param name="defaultValueCreator">A Func used to initialize default value for reference types.</param>
352 /// <returns>A newly created attached read-only BindablePropertyKey.</returns>
353 public static BindablePropertyKey CreateAttachedReadOnly(string propertyName, Type returnType, Type declaringType, object defaultValue, BindingMode defaultBindingMode = BindingMode.OneWayToSource,
354 ValidateValueDelegate validateValue = null, BindingPropertyChangedDelegate propertyChanged = null, BindingPropertyChangingDelegate propertyChanging = null,
355 CoerceValueDelegate coerceValue = null, CreateDefaultValueDelegate defaultValueCreator = null)
358 new BindablePropertyKey(CreateAttached(propertyName, returnType, declaringType, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, null, true,
359 defaultValueCreator));
363 /// Deprecated. Do not use.
365 /// <typeparam name="TDeclarer">The type of the declaring object.</typeparam>
366 /// <typeparam name="TPropertyType">The type of the property.</typeparam>
367 /// <param name="getter">An expression identifying the getter for the property using this BindableProperty as backing store.</param>
368 /// <param name="defaultValue">The default value for the property.</param>
369 /// <param name="defaultBindingMode">The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay.</param>
370 /// <param name="validateValue">A delegate to be run when a value is set. This parameter is optional. Default is null.</param>
371 /// <param name="propertyChanged">A delegate to be run when the value has changed. This parameter is optional. Default is null.</param>
372 /// <param name="propertyChanging">A delegate to be run when the value will change. This parameter is optional. Default is null.</param>
373 /// <param name="coerceValue">A delegate used to coerce the range of a value. This parameter is optional. Default is null.</param>
374 /// <param name="defaultValueCreator">A Func used to initialize default value for reference types.</param>
375 /// <returns>A newly created BindablePropertyKey.</returns>
376 [Obsolete("CreateReadOnly<> (generic) is obsolete as of version 2.1.0 and is no longer supported.")]
377 public static BindablePropertyKey CreateReadOnly<TDeclarer, TPropertyType>(Expression<Func<TDeclarer, TPropertyType>> getter, TPropertyType defaultValue,
378 BindingMode defaultBindingMode = BindingMode.OneWayToSource, ValidateValueDelegate<TPropertyType> validateValue = null,
379 BindingPropertyChangedDelegate<TPropertyType> propertyChanged = null, BindingPropertyChangingDelegate<TPropertyType> propertyChanging = null,
380 CoerceValueDelegate<TPropertyType> coerceValue = null, CreateDefaultValueDelegate<TDeclarer, TPropertyType> defaultValueCreator = null) where TDeclarer : BindableObject
382 return new BindablePropertyKey(Create(getter, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, null, true, defaultValueCreator));
386 /// Creates a new instance of the BindablePropertyKey class.
388 /// <param name="propertyName">The name of the BindableProperty.</param>
389 /// <param name="returnType">The type of the property.</param>
390 /// <param name="declaringType">The type of the declaring object.</param>
391 /// <param name="defaultValue">The default value for the property.</param>
392 /// <param name="defaultBindingMode">The BindingMode to use on SetBinding() if no BindingMode is given. This parameter is optional. Default is BindingMode.OneWay.</param>
393 /// <param name="validateValue">A delegate to be run when a value is set. This parameter is optional. Default is null.</param>
394 /// <param name="propertyChanged">A delegate to be run when the value has changed. This parameter is optional. Default is null.</param>
395 /// <param name="propertyChanging">A delegate to be run when the value will change. This parameter is optional. Default is null.</param>
396 /// <param name="coerceValue">A delegate used to coerce the range of a value. This parameter is optional. Default is null.</param>
397 /// <param name="defaultValueCreator">A Func used to initialize default value for reference types.</param>
398 /// <returns>A newly created BindablePropertyKey.</returns>
399 public static BindablePropertyKey CreateReadOnly(string propertyName, Type returnType, Type declaringType, object defaultValue, BindingMode defaultBindingMode = BindingMode.OneWayToSource,
400 ValidateValueDelegate validateValue = null, BindingPropertyChangedDelegate propertyChanged = null, BindingPropertyChangingDelegate propertyChanging = null,
401 CoerceValueDelegate coerceValue = null, CreateDefaultValueDelegate defaultValueCreator = null)
404 new BindablePropertyKey(new BindableProperty(propertyName, returnType, declaringType, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue,
405 isReadOnly: true, defaultValueCreator: defaultValueCreator));
408 [Obsolete("Create<> (generic) is obsolete as of version 2.1.0 and is no longer supported.")]
409 internal static BindableProperty Create<TDeclarer, TPropertyType>(Expression<Func<TDeclarer, TPropertyType>> getter, TPropertyType defaultValue, BindingMode defaultBindingMode,
410 ValidateValueDelegate<TPropertyType> validateValue, BindingPropertyChangedDelegate<TPropertyType> propertyChanged, BindingPropertyChangingDelegate<TPropertyType> propertyChanging,
411 CoerceValueDelegate<TPropertyType> coerceValue, BindablePropertyBindingChanging bindingChanging, bool isReadOnly = false,
412 CreateDefaultValueDelegate<TDeclarer, TPropertyType> defaultValueCreator = null) where TDeclarer : BindableObject
415 throw new ArgumentNullException("getter");
417 Expression expr = getter.Body;
419 var unary = expr as UnaryExpression;
421 expr = unary.Operand;
423 var member = expr as MemberExpression;
425 throw new ArgumentException("getter must be a MemberExpression", "getter");
427 var property = (PropertyInfo)member.Member;
429 ValidateValueDelegate untypedValidateValue = null;
430 BindingPropertyChangedDelegate untypedBindingPropertyChanged = null;
431 BindingPropertyChangingDelegate untypedBindingPropertyChanging = null;
432 CoerceValueDelegate untypedCoerceValue = null;
433 CreateDefaultValueDelegate untypedDefaultValueCreator = null;
434 if (validateValue != null)
435 untypedValidateValue = (bindable, value) => validateValue(bindable, (TPropertyType)value);
436 if (propertyChanged != null)
437 untypedBindingPropertyChanged = (bindable, oldValue, newValue) => propertyChanged(bindable, (TPropertyType)oldValue, (TPropertyType)newValue);
438 if (propertyChanging != null)
439 untypedBindingPropertyChanging = (bindable, oldValue, newValue) => propertyChanging(bindable, (TPropertyType)oldValue, (TPropertyType)newValue);
440 if (coerceValue != null)
441 untypedCoerceValue = (bindable, value) => coerceValue(bindable, (TPropertyType)value);
442 if (defaultValueCreator != null)
443 untypedDefaultValueCreator = o => defaultValueCreator((TDeclarer)o);
445 return new BindableProperty(property.Name, property.PropertyType, typeof(TDeclarer), defaultValue, defaultBindingMode, untypedValidateValue, untypedBindingPropertyChanged,
446 untypedBindingPropertyChanging, untypedCoerceValue, bindingChanging, isReadOnly, untypedDefaultValueCreator);
449 internal static BindableProperty Create(string propertyName, Type returnType, Type declaringType, object defaultValue, BindingMode defaultBindingMode, ValidateValueDelegate validateValue,
450 BindingPropertyChangedDelegate propertyChanged, BindingPropertyChangingDelegate propertyChanging, CoerceValueDelegate coerceValue, BindablePropertyBindingChanging bindingChanging,
451 CreateDefaultValueDelegate defaultValueCreator = null)
453 return new BindableProperty(propertyName, returnType, declaringType, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, bindingChanging,
454 defaultValueCreator: defaultValueCreator);
457 [Obsolete("CreateAttached<> (generic) is obsolete as of version 2.1.0 and is no longer supported.")]
458 internal static BindableProperty CreateAttached<TDeclarer, TPropertyType>(Expression<Func<BindableObject, TPropertyType>> staticgetter, TPropertyType defaultValue, BindingMode defaultBindingMode,
459 ValidateValueDelegate<TPropertyType> validateValue, BindingPropertyChangedDelegate<TPropertyType> propertyChanged, BindingPropertyChangingDelegate<TPropertyType> propertyChanging,
460 CoerceValueDelegate<TPropertyType> coerceValue, BindablePropertyBindingChanging bindingChanging, bool isReadOnly = false,
461 CreateDefaultValueDelegate<BindableObject, TPropertyType> defaultValueCreator = null)
463 if (staticgetter == null)
464 throw new ArgumentNullException("staticgetter");
466 Expression expr = staticgetter.Body;
468 var unary = expr as UnaryExpression;
470 expr = unary.Operand;
472 var methodcall = expr as MethodCallExpression;
473 if (methodcall == null)
474 throw new ArgumentException("staticgetter must be a MethodCallExpression", "staticgetter");
476 MethodInfo method = methodcall.Method;
477 if (!method.Name.StartsWith("Get", StringComparison.Ordinal))
478 throw new ArgumentException("staticgetter name must start with Get", "staticgetter");
480 string propertyname = method.Name.Substring(3);
482 ValidateValueDelegate untypedValidateValue = null;
483 BindingPropertyChangedDelegate untypedBindingPropertyChanged = null;
484 BindingPropertyChangingDelegate untypedBindingPropertyChanging = null;
485 CoerceValueDelegate untypedCoerceValue = null;
486 CreateDefaultValueDelegate untypedDefaultValueCreator = null;
487 if (validateValue != null)
488 untypedValidateValue = (bindable, value) => validateValue(bindable, (TPropertyType)value);
489 if (propertyChanged != null)
490 untypedBindingPropertyChanged = (bindable, oldValue, newValue) => propertyChanged(bindable, (TPropertyType)oldValue, (TPropertyType)newValue);
491 if (propertyChanging != null)
492 untypedBindingPropertyChanging = (bindable, oldValue, newValue) => propertyChanging(bindable, (TPropertyType)oldValue, (TPropertyType)newValue);
493 if (coerceValue != null)
494 untypedCoerceValue = (bindable, value) => coerceValue(bindable, (TPropertyType)value);
495 if (defaultValueCreator != null)
496 untypedDefaultValueCreator = o => defaultValueCreator(o);
498 return new BindableProperty(propertyname, method.ReturnType, typeof(TDeclarer), defaultValue, defaultBindingMode, untypedValidateValue, untypedBindingPropertyChanged, untypedBindingPropertyChanging,
499 untypedCoerceValue, bindingChanging, isReadOnly, untypedDefaultValueCreator);
502 internal static BindableProperty CreateAttached(string propertyName, Type returnType, Type declaringType, object defaultValue, BindingMode defaultBindingMode, ValidateValueDelegate validateValue,
503 BindingPropertyChangedDelegate propertyChanged, BindingPropertyChangingDelegate propertyChanging, CoerceValueDelegate coerceValue, BindablePropertyBindingChanging bindingChanging,
504 bool isReadOnly, CreateDefaultValueDelegate defaultValueCreator = null)
506 return new BindableProperty(propertyName, returnType, declaringType, defaultValue, defaultBindingMode, validateValue, propertyChanged, propertyChanging, coerceValue, bindingChanging, isReadOnly,
507 defaultValueCreator);
510 internal object GetDefaultValue(BindableObject bindable)
512 if (DefaultValueCreator != null)
513 return DefaultValueCreator(bindable);
518 internal bool TryConvert(ref object value)
522 return !ReturnTypeInfo.IsValueType || ReturnTypeInfo.IsGenericType && ReturnTypeInfo.GetGenericTypeDefinition() == typeof(Nullable<>);
525 Type valueType = value.GetType();
526 Type type = ReturnType;
528 // Dont support arbitrary IConvertible by limiting which types can use this
529 Type[] convertableTo;
530 TypeConverter typeConverterTo;
531 if (SimpleConvertTypes.TryGetValue(valueType, out convertableTo) && Array.IndexOf(convertableTo, type) != -1)
533 value = Convert.ChangeType(value, type);
535 else if (WellKnownConvertTypes.TryGetValue(type, out typeConverterTo) && typeConverterTo.CanConvertFrom(valueType))
537 value = typeConverterTo.ConvertFromInvariantString(value.ToString());
539 else if (UserCustomConvertTypes.TryGetValue(type, out typeConverterTo) && typeConverterTo.CanConvertFrom(valueType))
541 //Modification for NUI XAML : user defined converter for DynamicResource can be added
542 value = typeConverterTo.ConvertFromInvariantString(value.ToString());
544 else if (!ReturnTypeInfo.IsAssignableFrom(valueType.GetTypeInfo()))
546 var cast = type.GetImplicitConversionOperator(fromType: valueType, toType: type)
547 ?? valueType.GetImplicitConversionOperator(fromType: valueType, toType: type);
552 value = cast.Invoke(null, new[] { value });
558 internal delegate void BindablePropertyBindingChanging(BindableObject bindable, BindingBase oldValue, BindingBase newValue);