/// <summary> /// Initializes a new instance of the <see cref="PropertyModel"/> class based on given data; some restrictions are observed. /// </summary> /// <param name="Host"></param> /// <param name="Property"></param> /// <param name="Attributes"></param> /// <returns></returns> internal static PropertyModel New(object Host, PropertyInfo Property, PropertyAttributes Attributes, bool IsNested) { var Result = New(IsNested ? typeof(object) : Property.PropertyType); if (Result != null) { Result.Info = Property; var Name = Attributes.Get <DisplayNameAttribute, string>(); Name = Name.IsNullOrEmpty() ? Property.Name : Name; var Value = default(object); try { //Will fail if locked Value = Property.GetValue(Host); } catch (Exception) { //Do nothing! } //Set the important stuff first Result.Host = Host; Result.Name = Name; Result.Value = Value; //Set the minor stuff Result.Category = Attributes.Get <CategoryAttribute, string>(); Result.Description = Attributes.Get <DescriptionAttribute, string>(); Result.StringFormat = Attributes.Get <StringFormatAttribute, string>(); Result.IsFeatured = Attributes.Get <FeaturedAttribute, bool>(); //Honor the attribute if the property is settable; if it isn't, it is automatically readonly and should always be! if (Result.IsSettable) { Result.IsReadOnly = Attributes.Get <ReadOnlyAttribute, bool>(); } if (Result is PropertyModel <string> ) { Result.As <PropertyModel <string> >().Tag = Attributes.Get <StringKindAttribute, StringKind>(); } if (Result is PropertyModel <long> ) { Result.As <PropertyModel <long> >().Tag = Attributes.Get <Int64KindAttribute, Int64Kind>(); } //Honor constraints if (Result is ICoercable) { var Constraint = Attributes.Get <ConstraintAttribute, ConstraintAttribute>(); if (Constraint != null) { Result.As <ICoercable>().SetConstraint(Constraint.Minimum, Constraint.Maximum); } } } return(Result); }