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); }
GetSerializableDependencyProperties( Object serializableObject ) { TypeDependencyPropertyCache[] serializableDependencyProperties = null; TypeDependencyPropertiesCacheItem item = GetTypeDependencyPropertiesCacheItem(serializableObject); if (item != null) { TypeDependencyPropertyCache[] dependencyProperties = item.GetSerializableDependencyProperties(); int[] serializableIndeces = new int[dependencyProperties.Length]; int serializablePropertiesIndex = 0; // // Not everything we get can be serializable, so we have to figure out which // ones are by checking if we can also serialize the value of the property // values would be added to the cache as well. // for (int indexInDependencyProperties = 0; indexInDependencyProperties < dependencyProperties.Length; indexInDependencyProperties++) { if (TypeDependencyPropertyCache. CanSerializeValue(serializableObject, dependencyProperties[indexInDependencyProperties]) && _serializationManager.CanSerializeDependencyProperty(serializableObject, dependencyProperties[indexInDependencyProperties])) { serializableIndeces[serializablePropertiesIndex++] = indexInDependencyProperties; } } serializableDependencyProperties = new TypeDependencyPropertyCache[serializablePropertiesIndex]; for (int indexInSerializableDependencyProperties = 0; indexInSerializableDependencyProperties < serializablePropertiesIndex; indexInSerializableDependencyProperties++) { TypeDependencyPropertyCache propertyCache = dependencyProperties[serializableIndeces[indexInSerializableDependencyProperties]]; TypeDependencyPropertyCache serializablePropertyCache = new TypeDependencyPropertyCache(propertyCache.MemberInfo, propertyCache.DependencyProperty, propertyCache.Visibility, propertyCache.SerializerTypeForProperty, propertyCache.TypeConverterForProperty, propertyCache.DefaultValueAttr, propertyCache.DesignerSerializationOptionsAttr); serializablePropertyCache.PropertyValue = propertyCache.PropertyValue; serializableDependencyProperties[indexInSerializableDependencyProperties] = serializablePropertyCache; } // // Clear all set values // for (int indexInDependencyProperties = 0; indexInDependencyProperties < dependencyProperties.Length; indexInDependencyProperties++) { dependencyProperties[indexInDependencyProperties].PropertyValue = null; } } return(serializableDependencyProperties); }