/// <summary> /// Get all the <see cref="PackageProperty"/> values, including properties in base types. To get the properties declared only in this type, use <see cref="GetLocalNativeProperties"/>. Note that these <see cref="PackagePropertyAttribute"/> values will have overlapped indexes. /// </summary> /// <param name="type">The <see cref="Type"/> to search for properties within.</param> /// <returns>The collection of <see cref="PackageProperty"/> objects.</returns> public static PackagePropertyCollection GetNativeProperties(Type type) { PackagePropertyCollection collection; ObservableCollection <PackageProperty> list; if (NativePropertiesDictionary.TryGetValue(type, out collection)) { return(collection); } if (type.BaseType != null) { list = new ObservableCollection <PackageProperty>(GetNativeProperties(type.BaseType)); var properties = GetLocalNativeProperties(type); foreach (var item in properties) { list.Add(item); } } else { list = new ObservableCollection <PackageProperty>(GetLocalNativeProperties(type)); } collection = NativePropertiesDictionary[type] = new PackagePropertyCollection(list); return(collection); }
/// <summary> /// Get all the <see cref="PackageProperty"/> attributes that are defined within this <see cref="Type"/> (no inheritance). /// </summary> /// <param name="type">The <see cref="Type"/> to search for properties within.</param> /// <returns>The collection of <see cref="PackageProperty"/> objects.</returns> public static PackagePropertyCollection GetLocalNativeProperties(Type type) { PackagePropertyCollection collection; if (LocalNativePropertiesDictionary.TryGetValue(type, out collection)) { return(collection); } ObservableCollection <PackageProperty> list = new ObservableCollection <PackageProperty>(); collection = LocalNativePropertiesDictionary[type] = new PackagePropertyCollection(list); var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); foreach (var property in properties) { var attributes = property.GetCustomAttributes(typeof(PackagePropertyAttribute), false); if (attributes == null || attributes.Length == 0) { continue; } var attribute = (PackagePropertyAttribute)attributes[0]; while (list.Count <= attribute.Index) { list.Add(null); } if (list[attribute.Index] != null) { throw new Exception(type.Name + " has invalid NativePropertyAttributes - multiple attributes (including " + list[attribute.Index].Property.Name + " and " + property.Name + ") have the same index."); } var nativeProperty = list[attribute.Index] = new PackageProperty(property, attribute); attribute.AttachedProperty = property; if (attribute.Processor == null) { attribute.Processor = TypeProcessorAttribute.MustGetTypeProcessor(property.PropertyType); } } for (int index = 0; index < list.Count; index++) { if (list[index] == null) { throw new Exception(type.Name + " has invalid NativePropertyAttributes - there is no usage of " + index + ", and maybe others."); } } return(collection); }