// <summary> // Gets all relevant sub-properties from the value of the specified // ModelProperty // </summary> // <param name="property">ModelProperty to examine</param> // <returns>Sub-properties exposed by the value of the specified ModelProperty</returns> public static List <ModelProperty> GetSubProperties(ModelProperty property) { if (property.Value == null || ModelUtilities.GetSafeRawValue(property) == null) { return(null); } // First, see if there is a custom TypeConverter. If so, get the subProperties // from there. Otherwise, get all subProperties including those that aren't browsable, // since the Browsability call should be made by the UI, not by the model. return(GetTypeConverterSubProperties(property) ?? GetAllSubProperties(property)); }
// <summary> // Computes the IsReadOnly flag for the specified set of properties, ORing // results together for sets of properties larger than 1. // </summary> // <param name="properties">Properties to examine</param> // <param name="isMixedValueDelegate">Delegate that evaluates the IsMixedValue flag for // the passed in property values (added as an optimization, since we don't always require // the value and it may be computationally expensive)</param> // <returns>Flag indicating whether the set of properties is read only or not</returns> public static bool IsReadOnly(List <ModelProperty> properties, IsMixedValueEvaluator isMixedValueEvaluator) { if (properties == null || properties.Count == 0) { Debug.Fail("ExtensibilityAccessor.IsReadOnly: No properties specified."); return(true); } Type propertyType = properties[0].PropertyType; // ILists are readonly only if value is null if (typeof(IList).IsAssignableFrom(propertyType)) { if (OrReadOnlyValues(properties)) { IList list = null; if (isMixedValueEvaluator != null) { list = isMixedValueEvaluator() ? null : (ModelUtilities.GetSafeRawValue(properties[0]) as IList); } else { Debug.Fail("No delegate to evaluate IsMixedValue specified."); } if (list == null) { return(true); } } return(false); } // Arrays and ICollections are readonly if (typeof(Array).IsAssignableFrom(propertyType) || typeof(ICollection).IsAssignableFrom(propertyType)) { return(true); } // Types that implement ONLY ICollection<> or ONLY IList<> (meaning they // don't also implement ICollection or IList, which we handle above) // are also readonly if (ModelUtilities.ImplementsICollection(propertyType) || ModelUtilities.ImplementsIList(propertyType)) { return(true); } // Otherwise, go off of the IsReadOnly value in ModelProperty return(OrReadOnlyValues(properties)); }