/// <summary> /// Determines whether a property should be serialized (based upon the DefaultAttribute and ShouldSerialize methods). /// </summary> /// <param name = "obj">The object being serialized.</param> /// <param name = "propValue">The value of the property being serialized.</param> /// <param name = "prop">The property being serialized.</param> /// <returns>true if the property should be serialized, false otherwise.</returns> protected override bool ShouldSerialize(object obj, object propValue, PropertyInfo prop) { if (PropEquals.Equals(prop, ResourcesProperty) && propValue.GetType().Equals(typeof(ResourceDictionary)) && ((ResourceDictionary)propValue).Count == 0) { return(false); } if (obj is ListBox && PropEquals.Equals(prop, SelectedItemsProperty) && ((ListBox)obj).SelectionMode == SelectionMode.Single) { return(false); } if (obj is Selector && (PropEquals.Equals(prop, SelectedItemProperty) || PropEquals.Equals(prop, SelectedValueProperty))) { return(false); } if (obj is Binding && Equals(GetPropertyGetter(prop)(PrototypeBinding), propValue)) { return(false); } #if WINDOWS_PHONE if (obj is FrameworkElement && PropEquals.Equals(prop, CursorProperty) && propValue == null) { return(false); } #endif return(base.ShouldSerialize(obj, propValue, prop)); }
/// <summary> /// Determines whether the given property can be written inline (as an attribute) rather than using object-element syntax. /// </summary> /// <param name = "obj">The object on which the property is being set.</param> /// <param name = "propValue">The value of the property being set.</param> /// <param name = "inf">The identifier for the property being set (a PropertyInfo for a property, and the getter MethodInfo for an attached property).</param> /// <param name = "cycleCheckObjects">The set of objects on the stack (for cycle detection).</param> /// <returns></returns> protected override bool IsInlinable(object obj, object propValue, MemberInfo inf, ISet <object> cycleCheckObjects) { try { var dObj = obj as DependencyObject; if (dObj != null) { DependencyProperty dp = null; if (inf is PropertyInfo) { dp = this.GetDependencyProperty((PropertyInfo)inf); } else if (inf is MethodInfo) { dp = this.GetDependencyProperty((MethodInfo)inf); } if (dp != null) { if (!this._IncludeUnsetValues && dObj.ReadLocalValue(dp) == DependencyProperty.UnsetValue) { return(true); } Binding binding = GetBinding(dObj, dp); if (this._SerializeBindings && binding != null) { return(false); } } } if (propValue != null && this.State.Resources.ContainsKey(propValue)) { return(true); } if (propValue is Type && inf.Name.Equals("TargetType") && (inf.DeclaringType.Equals(typeof(Style)) || inf.DeclaringType.Equals(typeof(ControlTemplate)))) { return(true); } if ((inf is PropertyInfo && ((PropertyInfo)inf).PropertyType.Equals(typeof(PropertyPath))) || (inf is MethodInfo && ((MethodInfo)inf).ReturnType.Equals(typeof(PropertyPath)))) { return(true); } if (PropEquals.Equals(inf as PropertyInfo, SetterPropertyProperty)) { return(true); } } catch (Exception e) { Debug.WriteLine(e.ToString()); } return(base.IsInlinable(obj, propValue, inf, cycleCheckObjects)); }
/// <summary> /// Gets a string for a property used to determine the order in which properties will be serialized. /// </summary> /// <param name = "prop">The property being serialized.</param> /// <returns>A sortable string representation for the property.</returns> protected override string GetPropertyOrder(PropertyInfo prop) { if (PropEquals.Equals(prop, ResourcesProperty)) { return("" + char.MinValue); } return(base.GetPropertyOrder(prop)); }
/// <summary> /// Serializes a property. /// </summary> /// <param name = "obj">The object on which the property is set.</param> /// <param name = "propValue">The value of the property.</param> /// <param name = "prop">The property being set.</param> /// <param name = "isContentProperty">A value indicating that the property is the ContentProperty for the object, and thus no property elements need to be generated.</param> /// <param name = "writer">The writer being used for serialization.</param> /// <param name = "prefixMappings">A mapping of xml namespaces to prefixes.</param> /// <param name = "cycleCheckObjects">The set of objects on the stack (for cycle detection).</param> protected override void VisitProperty(object obj, object propValue, PropertyInfo prop, bool isContentProperty, XmlWriter writer, IDictionary <string, string> prefixMappings, ISet <object> cycleCheckObjects) { if (obj is ResourceDictionary && prop.Name.Equals("Source") && prop.DeclaringType.Equals(typeof(ResourceDictionary)) && (propValue == null || ((Uri)propValue).OriginalString.Equals(string.Empty))) { return; } if (obj is Setter && prop.Name.Equals("Property") && prop.DeclaringType.Equals(typeof(Setter))) { Setter s = obj as Setter; var dp = (from p in StyleTypePropertyCache.ContainsKey(this.State.StyleTypeStack.Peek()) ? StyleTypePropertyCache[this.State.StyleTypeStack.Peek()] : StyleTypePropertyCache[this.State.StyleTypeStack.Peek()] = this.State.StyleTypeStack.Peek().GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance) let dProp = GetDependencyProperty(p) where dProp != null && dProp == s.Property select new { Property = p, DependencyProperty = dProp }).FirstOrDefault(); if (dp != null) { this.VisitPropertyPath(dp.Property.Name, "Property", null, writer, prefixMappings, cycleCheckObjects); return; } var adp = (from ap in this.GetAttachedProperties(this.State.StyleTypeStack.Peek()) let dProp = GetDependencyProperty(ap.Getter) where dProp != null && dProp == s.Property select new { Property = ap, DependencyProperty = dProp }).FirstOrDefault(); if (adp != null) { string ns = this.GetNamespace(adp.Property.Getter.DeclaringType, prefixMappings); string prefix = this.GetPrefix(ns, prefixMappings, writer); string path = string.Empty.Equals(prefix) ? string.Format("{0}.{1}", adp.Property.Getter.DeclaringType.Name, adp.Property.Name) : string.Format("{0}:{1}.{2}", prefix, adp.Property.Getter.DeclaringType.Name, adp.Property.Name); this.VisitPropertyPath(path, "Property", null, writer, prefixMappings, cycleCheckObjects); return; } } if (propValue is Type && prop.Name.Equals("TargetType") && (prop.DeclaringType.Equals(typeof(Style)) || prop.DeclaringType.Equals(typeof(ControlTemplate)))) { string ns = this.GetNamespace(propValue as Type, prefixMappings); string prefix = writer.LookupPrefix(ns); if (prefix == null) { prefix = this.GetPrefix(ns, prefixMappings, writer); writer.WriteAttributeString("xmlns", prefix, null, ns); } if (!string.IsNullOrEmpty(prefix)) { prefix = prefix + ":"; } writer.WriteAttributeString(prop.Name, prefix + ((Type)propValue).Name); return; } if (prop.PropertyType.Equals(typeof(PropertyPath)) && propValue != null) { this.VisitPropertyPath((propValue as PropertyPath).Path, prop.Name, null, writer, prefixMappings, cycleCheckObjects); return; } if (propValue != null && this.State.Resources.ContainsKey(propValue)) { writer.WriteAttributeString(prop.Name, string.Format("{{StaticResource {0}}}", this.State.Resources[propValue])); return; } #if WINDOWS_PHONE if (propValue.GetType().Equals(typeof(RelativeSource))) { VisitProperty(obj, new Phone.DerivedRelativeSource(propValue as RelativeSource), prop, isContentProperty, writer, prefixMappings, cycleCheckObjects); return; } #endif var dObj = obj as DependencyObject; if (dObj != null) { DependencyProperty dp = GetDependencyProperty(prop); if (dp != null) { if (!this._IncludeUnsetValues && dObj.ReadLocalValue(dp) == DependencyProperty.UnsetValue) { return; } Binding binding = GetBinding(dObj, dp); if (this._SerializeBindings && binding != null) { base.VisitProperty(obj, binding, prop, isContentProperty, writer, prefixMappings, cycleCheckObjects); return; } } } if (PropEquals.Equals(prop, ResourcesProperty)) { this.State.IsInResources = true; } base.VisitProperty(obj, propValue, prop, isContentProperty, writer, prefixMappings, cycleCheckObjects); if (PropEquals.Equals(prop, ResourcesProperty)) { this.State.IsInResources = false; } }