CanSerializeProperty( MemberInfo memberInfo, SerializersCacheManager serializersCacheManager, out DesignerSerializationVisibility visibility, out Type serializerTypeForProperty, out TypeConverter typeConverterForProperty, out DefaultValueAttribute defaultValueAttr, out DesignerSerializationOptionsAttribute designerSerializationFlagsAttr ) { bool canSerializeProperty = false; // The conditions that we care about in those properties are as follows // 1. Properties that are decorated with the DesignerSerializationVisibility // and that are not hidden // visibility = DesignerSerializationVisibility.Visible; serializerTypeForProperty = null; typeConverterForProperty = null; defaultValueAttr = null; designerSerializationFlagsAttr = null; Attribute[] attributes = Attribute.GetCustomAttributes(memberInfo); for (int numberOfAttributes = 0; numberOfAttributes < attributes.Length; numberOfAttributes++) { // // Based on the attribute type, different properties could be set // Attribute attribute = attributes[numberOfAttributes]; if (attribute is DesignerSerializationVisibilityAttribute) { visibility = ((DesignerSerializationVisibilityAttribute)attribute).Visibility; } else if (attribute is DefaultValueAttribute) { defaultValueAttr = (DefaultValueAttribute)attribute; } else if (attribute is DesignerSerializationOptionsAttribute) { designerSerializationFlagsAttr = (DesignerSerializationOptionsAttribute)attribute; } } if (visibility != DesignerSerializationVisibility.Hidden) { canSerializeProperty = true; } return(canSerializeProperty); }
TypeDependencyPropertyCache( MemberInfo memberInfo, Object dependencyProperty, DesignerSerializationVisibility visibility, Type serializerTypeForProperty, TypeConverter typeConverterForProperty, DefaultValueAttribute defaultValueAttr, DesignerSerializationOptionsAttribute designerSerializationFlagsAttr ) : base() { this.MemberInfo = memberInfo; this.DependencyProperty = dependencyProperty; this.PropertyInfo = memberInfo as PropertyInfo; this.Visibility = visibility; this.SerializerTypeForProperty = serializerTypeForProperty; this.TypeConverterForProperty = typeConverterForProperty; this.DefaultValueAttr = defaultValueAttr; this.DesignerSerializationOptionsAttr = designerSerializationFlagsAttr; this.PropertyValue = null; }
TypePropertyCache( PropertyInfo propertyInfo, DesignerSerializationVisibility visibility, Type serializerTypeForProperty, TypeConverter typeConverterForProperty, DefaultValueAttribute defaultValueAttr, DesignerSerializationOptionsAttribute designerSerializationFlagsAttr ) { if (propertyInfo == null) { throw new ArgumentNullException("propertyInfo"); } this.propertyInfo = propertyInfo; this.visibility = visibility; this.serializerTypeForProperty = serializerTypeForProperty; this.typeConverterForProperty = typeConverterForProperty; this.defaultValueAttr = defaultValueAttr; this.designerSerializationFlagsAttr = designerSerializationFlagsAttr; this.propertyValue = null; }
GetTypeDependencyPropertiesCacheItem( Object serializableObject ) { if (serializableObject == null) { throw new ArgumentNullException("serializableObject"); } Type type = serializableObject.GetType(); TypeDependencyPropertiesCacheItem cachedItem = (TypeDependencyPropertiesCacheItem)_typesDependencyPropertiesCacheTable[type]; if (cachedItem == null) { // // This means that the type was not seen before // We have to create a new entry to that type // DependencyObject objectAsDependencyObject = serializableObject as DependencyObject; if (objectAsDependencyObject != null) { // // First we have to figure out if this dependency // object has any dependency properties that can be // serializable and this has to happen before creating // any cache // DependencyPropertyList list = new DependencyPropertyList(1); for (LocalValueEnumerator localValues = objectAsDependencyObject.GetLocalValueEnumerator(); localValues.MoveNext();) { DependencyProperty dependencyProperty = localValues.Current.Property; list.Add(dependencyProperty); } if (list.Count > 0) { int numOfSerializableDependencyProperties = 0; TypeDependencyPropertyCache[] dependencyPropertiesCache = new TypeDependencyPropertyCache[list.Count]; for (int indexInDependencyPropertyList = 0; indexInDependencyPropertyList < list.Count; indexInDependencyPropertyList++) { DependencyProperty dependencyProperty = list.List[indexInDependencyPropertyList]; DesignerSerializationVisibility visibility = DesignerSerializationVisibility.Visible; Type serializerTypeForProperty = null; TypeConverter typeConverterForProperty = null; DefaultValueAttribute defaultValueAttr = null; DesignerSerializationOptionsAttribute designerSerializationFlagsAttr = null; Type propertyType = dependencyProperty.PropertyType; // // Get the static setter member for the DependencyProperty // MemberInfo memberInfo = dependencyProperty. OwnerType. GetMethod("Get" + dependencyProperty.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy); // Note: This is because the IService model does not abide // by this pattern of declaring the DependencyProperty on // the OwnerType. That is the only exception case. if (memberInfo == null) { // // Create a PropertyInfo // PropertyInfo propertyInfo = null; PropertyInfo[] properties = dependencyProperty.OwnerType.GetProperties(); String name = dependencyProperty.Name; for (int i = 0; i < properties.Length && propertyInfo == null; i++) { if (properties[i].Name == name) { propertyInfo = properties[i]; } } if (propertyInfo != null) { Debug.Assert(propertyInfo.PropertyType == dependencyProperty.PropertyType, "The property type of the CLR wrapper must match that of the DependencyProperty itself."); memberInfo = propertyInfo; // // We have to special case Print Tickets here. // Print Tickets are defined on as dependency properties on // fixed objects of types: // o FixedDocumentSequence // o FixedDocument // o FixedPage // and in order to eliminate the dependency between // PresentationFramework and System.printing assemblies, // those dependency properties are defined as of type "object" // and hence if we are here and we have a property of name // "PrintTicket" and owned by one of the above mentioned types // we try to get the serializer for the PrintTicket object // if (propertyInfo.Name == XpsNamedProperties.PrintTicketProperty && ((dependencyProperty.OwnerType == typeof(System.Windows.Documents.FixedPage)) || (dependencyProperty.OwnerType == typeof(System.Windows.Documents.FixedDocument)) || (dependencyProperty.OwnerType == typeof(System.Windows.Documents.FixedDocumentSequence)))) { propertyType = typeof(PrintTicket); } } } if (memberInfo != null && TypeDependencyPropertyCache. CanSerializeProperty(memberInfo, this, out visibility, out serializerTypeForProperty, out typeConverterForProperty, out defaultValueAttr, out designerSerializationFlagsAttr) == true) { TypeCacheItem typeCacheItem = GetTypeCacheItem(propertyType); serializerTypeForProperty = serializerTypeForProperty == null ? typeCacheItem.SerializerType : serializerTypeForProperty; typeConverterForProperty = typeConverterForProperty == null ? typeCacheItem.TypeConverter : typeConverterForProperty; TypeDependencyPropertyCache dependencyPropertyCache = new TypeDependencyPropertyCache(memberInfo, dependencyProperty, visibility, serializerTypeForProperty, typeConverterForProperty, defaultValueAttr, designerSerializationFlagsAttr); dependencyPropertiesCache[numOfSerializableDependencyProperties++] = dependencyPropertyCache; } } if (numOfSerializableDependencyProperties > 0) { TypeDependencyPropertyCache[] serializableDependencyPropertiesCache = new TypeDependencyPropertyCache[numOfSerializableDependencyProperties]; for (int indexInSerializableProperties = 0; indexInSerializableProperties < numOfSerializableDependencyProperties; indexInSerializableProperties++) { serializableDependencyPropertiesCache[indexInSerializableProperties] = dependencyPropertiesCache[indexInSerializableProperties]; } cachedItem = new TypeDependencyPropertiesCacheItem(type, serializableDependencyPropertiesCache); _typesDependencyPropertiesCacheTable[type] = cachedItem; } } } } return(cachedItem); }
GetClrSerializableProperties( SerializersCacheManager serializersCacheManager ) { if (clrSerializableProperties == null) { PropertyInfo[] properties = type.GetProperties(); // // Separate out the serializable Clr properties // int IndexOfSerializableProperties = 0; int[] propertiesIndex = new int[properties.Length]; TypePropertyCache[] cachedProperties = new TypePropertyCache[properties.Length]; for (int indexInProperties = 0; indexInProperties < properties.Length; indexInProperties++) { PropertyInfo propertyInfo = properties[indexInProperties]; DesignerSerializationVisibility visibility = DesignerSerializationVisibility.Visible; Type serializerTypeForProperty = null; TypeConverter typeConverterForProperty = null; DefaultValueAttribute defaultValueAttr = null; DesignerSerializationOptionsAttribute designerSerializationFlagsAttr = null; if (CanSerializeProperty(propertyInfo, serializersCacheManager, out visibility, out serializerTypeForProperty, out typeConverterForProperty, out defaultValueAttr, out designerSerializationFlagsAttr) == true) { // // Figure out the Serializer or TypeConverter associated with the // type of that property. This would potentially be cached in 2 // different places // 1. The Type Cache // 2. The TypePropertyCache. // TypeCacheItem typeCacheItem = serializersCacheManager.GetTypeCacheItem(propertyInfo.PropertyType); serializerTypeForProperty = typeCacheItem.SerializerType; typeConverterForProperty = typeCacheItem.TypeConverter; // // We create a cache of this property and all the information we // deduced about it // TypePropertyCache propertyCache = new TypePropertyCache(propertyInfo, visibility, serializerTypeForProperty, typeConverterForProperty, defaultValueAttr, designerSerializationFlagsAttr); propertiesIndex[IndexOfSerializableProperties] = indexInProperties; cachedProperties[IndexOfSerializableProperties++] = propertyCache; } } clrSerializableProperties = new TypePropertyCache[IndexOfSerializableProperties]; for (int indexInClrProperties = 0; indexInClrProperties < IndexOfSerializableProperties; indexInClrProperties++) { clrSerializableProperties[indexInClrProperties] = cachedProperties[indexInClrProperties]; } } return(clrSerializableProperties); }
CanSerializeProperty( PropertyInfo propertyInfo, SerializersCacheManager serializersCacheManager, out DesignerSerializationVisibility visibility, out Type serializerTypeForProperty, out TypeConverter typeConverterForProperty, out DefaultValueAttribute defaultValueAttr, out DesignerSerializationOptionsAttribute designerSerializationFlagsAttr ) { bool canSerializeProperty = false; visibility = DesignerSerializationVisibility.Visible; serializerTypeForProperty = null; typeConverterForProperty = null; defaultValueAttr = null; designerSerializationFlagsAttr = null; // The conditions that we care about in those properties are as follows // 1. Readable properties // 2. None Indexable Properteis. // So we can't deal with properties that take name: Item OR // take the form this[index1, index2, ...] // 3. Properties that are not backed up by a dependency property // 4. Properties that are decorated with the DesignerSerializationVisibility // and that are not hidden // if (propertyInfo.CanRead && propertyInfo.GetIndexParameters().GetLength(0) == 0) { MemberInfo memberInfo = (MemberInfo)propertyInfo; Attribute[] attributes = Attribute.GetCustomAttributes(memberInfo); for (int numberOfAttributes = 0; numberOfAttributes < attributes.Length; numberOfAttributes++) { // // Based on the attribute type, different properties could be set // Attribute attribute = attributes[numberOfAttributes]; if (attribute is DesignerSerializationVisibilityAttribute) { visibility = ((DesignerSerializationVisibilityAttribute)attribute).Visibility; } else if (attribute is DefaultValueAttribute) { defaultValueAttr = (DefaultValueAttribute)attribute; } else if (attribute is DesignerSerializationOptionsAttribute) { designerSerializationFlagsAttr = (DesignerSerializationOptionsAttribute)attribute; } } object DependencyPropertyORPropertyInfo = DependencyProperty.FromName(propertyInfo.Name, propertyInfo.DeclaringType); if (DependencyPropertyORPropertyInfo == null && visibility != DesignerSerializationVisibility.Hidden && (propertyInfo.CanWrite || visibility == DesignerSerializationVisibility.Content)) { if (visibility != DesignerSerializationVisibility.Hidden) { canSerializeProperty = true; } } } return(canSerializeProperty); }