/// <summary> /// Gets the Xaml string of the <paramref name="xamlObject"/> /// </summary> /// <param name="xamlObject">The object whose Xaml is requested.</param> public static string GetXaml(XamlObject xamlObject) { if (xamlObject != null) { var nd = xamlObject.XmlElement.CloneNode(true); var attLst = nd.Attributes.Cast<XmlAttribute>().ToDictionary(x => x.Name); var ns = new List<XmlAttribute>(); var parentObject = xamlObject.ParentObject; while (parentObject != null) { foreach (XmlAttribute attribute in parentObject.XmlElement.Attributes) { if (attribute.Name.StartsWith("xmlns:")) { if (!attLst.ContainsKey(attribute.Name)) { nd.Attributes.Append((XmlAttribute)attribute.CloneNode(false)); attLst.Add(attribute.Name, attribute); } } } parentObject = parentObject.ParentObject; } return nd.OuterXml; } return null; }
/// <summary> /// Creates a new XamlObjectServiceProvider instance. /// </summary> public XamlObjectServiceProvider(XamlObject obj) { if (obj == null) throw new ArgumentNullException("obj"); XamlObject = obj; Resolver = new XamlTypeResolverProvider(obj); }
/// <summary> /// Generates XAML markup extension code for the object. /// </summary> public static string Print(XamlObject obj) { StringBuilder sb = new StringBuilder(); sb.Append("{"); sb.Append(obj.GetNameForMarkupExtension()); bool first = true; foreach (var property in obj.Properties) { if (!property.IsSet) continue; if (first) sb.Append(" "); else sb.Append(", "); first = false; sb.Append(property.GetNameForMarkupExtension()); sb.Append("="); var value = property.PropertyValue; if (value is XamlTextValue) { sb.Append((value as XamlTextValue).Text); } else if (value is XamlObject) { sb.Append(Print(value as XamlObject)); } } sb.Append("}"); return sb.ToString(); }
/// <summary> /// Finds the XAML namescope for the specified object and uses it to unregister the old name and then register the new name. /// </summary> /// <param name="namedObject">The object where the name was changed.</param> /// <param name="oldName">The old name.</param> /// <param name="newName">The new name.</param> public static void NameChanged(XamlObject namedObject, string oldName, string newName) { var obj = namedObject; while (obj != null) { var nameScope = obj.Instance as INameScope; if (nameScope == null) { var depObj = obj.Instance as DependencyObject; if (depObj != null) nameScope = NameScope.GetNameScope(depObj); } if (nameScope != null) { if (oldName != null) { try { nameScope.UnregisterName(oldName); } catch (Exception x) { Debug.WriteLine(x.Message); } } if (newName != null) { nameScope.RegisterName(newName, namedObject.Instance); try{ var prp = namedObject.ElementType.GetProperty(namedObject.RuntimeNameProperty); if (prp != null) prp.SetValue(namedObject.Instance, newName, null); } catch (Exception x) { Debug.WriteLine(x.Message); } } break; } obj = obj.ParentObject; } }
public XamlTypeResolverProvider(XamlObject containingObject) { if (containingObject == null) throw new ArgumentNullException("containingObject"); this.document = containingObject.OwnerDocument; this.containingObject = containingObject; }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="xamlObject">The <see cref="XamlObject"/> object that represents the markup extension.</param> protected MarkupExtensionWrapper(XamlObject xamlObject) { if (xamlObject == null) { throw new ArgumentNullException("xamlObject"); } XamlObject = xamlObject; }
/// <summary> /// Gets whether shorthand XAML markup extension code can be generated for the object. /// </summary> public static bool CanPrint(XamlObject obj) { if (obj.ElementType == typeof(System.Windows.Data.MultiBinding) || obj.ElementType == typeof(System.Windows.Data.PriorityBinding)) { return false; } return CanPrint(obj, false, GetNonMarkupExtensionParent(obj)); }
/// <summary> /// Creates a new XamlObjectServiceProvider instance. /// </summary> public XamlObjectServiceProvider(XamlObject obj) { if (obj == null) { throw new ArgumentNullException("obj"); } XamlObject = obj; Resolver = new XamlTypeResolverProvider(obj); }
/// <summary> /// Generates XAML markup extension code for the object. /// </summary> public static string Print(XamlObject obj) { StringBuilder sb = new StringBuilder(); sb.Append("{"); sb.Append(obj.GetNameForMarkupExtension()); bool first = true; foreach (var property in obj.Properties) { if (!property.IsSet) { continue; } if (first) { sb.Append(" "); } else { sb.Append(", "); } first = false; sb.Append(property.GetNameForMarkupExtension()); sb.Append("="); var value = property.PropertyValue; var textValue = value as XamlTextValue; if (textValue != null) { string text = textValue.Text; bool containsSpace = text.Contains(' '); if (containsSpace) { sb.Append('\''); } sb.Append(text.Replace("\\", "\\\\")); if (containsSpace) { sb.Append('\''); } } else if (value is XamlObject) { sb.Append(Print(value as XamlObject)); } } sb.Append("}"); return(sb.ToString()); }
/// <summary> /// Method use to parse a piece of Xaml. /// </summary> /// <param name="root">The Root XamlObject of the current document.</param> /// <param name="xaml">The Xaml being parsed.</param> /// <param name="settings">Parser settings used by <see cref="XamlParser"/>.</param> /// <returns>Returns the XamlObject of the parsed <paramref name="xaml"/>.</returns> public static XamlObject ParseSnippet(XamlObject root, string xaml, XamlParserSettings settings) { XmlTextReader reader = new XmlTextReader(new StringReader(xaml)); var element = root.OwnerDocument.XmlDocument.ReadNode(reader); if (element != null) { XmlAttribute xmlnsAttribute = null; foreach (XmlAttribute attrib in element.Attributes) { if (attrib.Name == "xmlns") { xmlnsAttribute = attrib; } } if (xmlnsAttribute != null) { element.Attributes.Remove(xmlnsAttribute); } //Remove namespace Attributes defined in the Xaml Root from the Pasted Snippet! List <XmlAttribute> removeAttributes = new List <XmlAttribute>(); foreach (XmlAttribute attrib in element.Attributes) { if (attrib.Name.StartsWith("xmlns:")) { var rootPrefix = root.OwnerDocument.GetPrefixForNamespace(attrib.Value); if (rootPrefix == null) { //todo: check if we can add to root, (maybe same ns exists) root.OwnerDocument.XmlDocument.Attributes.Append((XmlAttribute)attrib.CloneNode(true)); removeAttributes.Add(attrib); } else if (rootPrefix == attrib.Name.Substring(6)) { removeAttributes.Add(attrib); } } } foreach (var removeAttribute in removeAttributes) { element.Attributes.Remove(removeAttribute); } //end remove XamlParser parser = new XamlParser(); parser.settings = settings; parser.document = root.OwnerDocument; var xamlObject = parser.ParseObject(element as XmlElement); if (xamlObject != null) { return(xamlObject); } } return(null); }
public DummyTypeDescriptorContext(XamlDocument document, XamlObject containingObject) { if (containingObject != null) { if (containingObject.OwnerDocument != document) throw new ArgumentException("Containing object must belong to the document!"); baseServiceProvider = containingObject.ServiceProvider; } else { baseServiceProvider = document.ServiceProvider; } }
/// <summary> /// Gets whether shorthand XAML markup extension code can be generated for the object. /// </summary> public static bool CanPrint(XamlObject obj) { if (obj.ElementType == typeof(System.Windows.Data.MultiBinding) || obj.ElementType == typeof(System.Windows.Data.PriorityBinding)) { return(false); } return(CanPrint(obj, false, GetNonMarkupExtensionParent(obj))); }
internal XamlProperty(XamlObject parentObject, XamlPropertyInfo propertyInfo) { this.parentObject = parentObject; this.propertyInfo = propertyInfo; if (propertyInfo.IsCollection) { isCollection = true; collectionElements = new CollectionElementsCollection(this); } }
/// <summary> /// Create a XamlPropertyValue for the specified value instance. /// </summary> public XamlPropertyValue CreatePropertyValue(object instance, XamlProperty forProperty) { if (instance == null) { throw new ArgumentNullException("instance"); } Type elementType = instance.GetType(); TypeConverter c = TypeDescriptor.GetConverter(instance); var ctx = new DummyTypeDescriptorContext(this.ServiceProvider); ctx.Instance = instance; bool hasStringConverter = c.CanConvertTo(ctx, typeof(string)) && c.CanConvertFrom(typeof(string)); if (forProperty != null && hasStringConverter) { return(new XamlTextValue(this, c.ConvertToInvariantString(ctx, instance))); } string ns = GetNamespaceFor(elementType); string prefix = GetPrefixForNamespace(ns); XmlElement xml = _xmlDoc.CreateElement(prefix, elementType.Name, ns); if (hasStringConverter && (XamlObject.GetContentPropertyName(elementType) != null || IsNativeType(instance))) { xml.InnerText = c.ConvertToInvariantString(instance); } else if (instance is Brush && forProperty != null) // TODO: this is a hacky fix, because Brush Editor doesn't // edit Design Items and so we have no XML, only the Brush // object and we need to parse the Brush to XAML! { var s = new MemoryStream(); XamlWriter.Save(instance, s); s.Seek(0, SeekOrigin.Begin); XmlDocument doc = new XmlDocument(); doc.Load(s); xml = (XmlElement)_xmlDoc.ImportNode(doc.DocumentElement, true); var attLst = xml.Attributes.Cast <XmlAttribute>().ToList(); foreach (XmlAttribute att in attLst) { if (att.Name.StartsWith(XamlConstants.Xmlns)) { var rootAtt = doc.DocumentElement.GetAttributeNode(att.Name); if (rootAtt != null && rootAtt.Value == att.Value) { xml.Attributes.Remove(att); } } } } return(new XamlObject(this, xml, elementType, instance)); }
/// <summary> /// Removes namespace attributes defined in the root from the specified node and all child nodes. /// </summary> static void RemoveRootNamespacesFromNodeAndChildNodes(XamlObject root, XmlNode node) { foreach (XmlNode childNode in node.ChildNodes) { RemoveRootNamespacesFromNodeAndChildNodes(root, childNode); } if (node.Attributes != null) { List <XmlAttribute> removeAttributes = new List <XmlAttribute>(); foreach (XmlAttribute attrib in node.Attributes) { if (attrib.Name.StartsWith("xmlns:")) { var prefixName = attrib.Name.Substring("xmlns:".Length); var rootPrefix = root.OwnerDocument.GetPrefixForNamespace(attrib.Value); if (rootPrefix == null) { var ns = root.OwnerDocument.GetNamespaceForPrefix(prefixName); if (string.IsNullOrEmpty(ns)) { root.OwnerDocument.XmlDocument.DocumentElement.Attributes.Append((XmlAttribute)attrib.CloneNode(true)); removeAttributes.Add(attrib); } } else if (rootPrefix == prefixName) { removeAttributes.Add(attrib); } else { var ns = root.OwnerDocument.GetNamespaceForPrefix(prefixName); if (string.IsNullOrEmpty(ns)) { root.OwnerDocument.XmlDocument.DocumentElement.Attributes.Append((XmlAttribute)attrib.CloneNode(true)); removeAttributes.Add(attrib); } else if (ns == attrib.Value) { removeAttributes.Add(attrib); } } } else if (attrib.Name == "xmlns" && attrib.Value == XamlConstants.PresentationNamespace) { removeAttributes.Add(attrib); } } foreach (var removeAttribute in removeAttributes) { node.Attributes.Remove(removeAttribute); } } }
/// <summary> /// Generates XAML markup extension code for the object. /// </summary> public static string Print(XamlObject obj) { StringBuilder sb = new StringBuilder(); sb.Append("{"); sb.Append(obj.GetNameForMarkupExtension()); bool first = true; var properties = obj.Properties.ToList(); if (obj.ElementType == typeof(Binding)){ var p=obj.Properties.FirstOrDefault(x=>x.PropertyName=="Path"); if (p!=null && p.IsSet) { sb.Append(" "); AppendPropertyValue(sb, p.PropertyValue, false); properties.Remove(p); first = false; } } else if (obj.ElementType == typeof(Reference)){ var p=obj.Properties.FirstOrDefault(x=>x.PropertyName=="Name"); if (p!=null && p.IsSet) { sb.Append(" "); AppendPropertyValue(sb, p.PropertyValue, false); properties.Remove(p); first = false; } } else if (obj.ElementType == typeof(StaticResourceExtension)){ var p=obj.Properties.FirstOrDefault(x=>x.PropertyName=="ResourceKey"); if (p!=null && p.IsSet) { sb.Append(" "); AppendPropertyValue(sb, p.PropertyValue, false); properties.Remove(p); first = false; } } foreach (var property in properties) { if (!property.IsSet) continue; if (first) sb.Append(" "); else sb.Append(", "); first = false; sb.Append(property.GetNameForMarkupExtension()); sb.Append("="); AppendPropertyValue(sb, property.PropertyValue, property.ReturnType == typeof(string)); } sb.Append("}"); return sb.ToString(); }
private static XamlObject GetNonMarkupExtensionParent(XamlObject markupExtensionObject) { System.Diagnostics.Debug.Assert(markupExtensionObject.IsMarkupExtension); XamlObject obj = markupExtensionObject; while (obj != null && obj.IsMarkupExtension) { obj = obj.ParentObject; } return(obj); }
void UpdateChildMarkupExtensions(XamlObject obj) { foreach (XamlObject propXamlObject in obj.Properties.Where((prop) => prop.IsSet).Select((prop) => prop.PropertyValue).OfType <XamlObject>()) { UpdateChildMarkupExtensions(propXamlObject); } if (obj.IsMarkupExtension && obj.ParentProperty != null) { obj.ParentProperty.UpdateValueOnInstance(); } }
/// <summary> /// Gets the type descriptor context used for type conversions. /// </summary> /// <param name="containingObject">The containing object, used when the /// type descriptor context needs to resolve an XML namespace.</param> internal ITypeDescriptorContext GetTypeDescriptorContext(XamlObject containingObject) { IServiceProvider serviceProvider; if (containingObject != null) { if (containingObject.OwnerDocument != this) throw new ArgumentException("Containing object must belong to the document!"); serviceProvider = containingObject.ServiceProvider; } else { serviceProvider = this.ServiceProvider; } return new DummyTypeDescriptorContext(serviceProvider); }
// for use by parser only internal XamlProperty(XamlObject parentObject, XamlPropertyInfo propertyInfo, XamlPropertyValue propertyValue) : this(parentObject, propertyInfo) { PossiblyNameChanged(null, propertyValue); this.propertyValue = propertyValue; if (propertyValue != null) { propertyValue.ParentProperty = this; } UpdateValueOnInstance(); }
static XamlProperty FindExistingXamlProperty(XamlObject obj, XamlPropertyInfo propertyInfo) { foreach (XamlProperty existing in obj.Properties) { if (existing.propertyInfo.FullyQualifiedName == propertyInfo.FullyQualifiedName) { return(existing); } } throw new XamlLoadException("Existing XamlProperty " + propertyInfo.FullyQualifiedName + " not found."); }
/// <summary> /// Create an XamlObject from the instance. /// </summary> public XamlObject CreateObject(object instance, object baseobject = null) { object obj = instance; if (baseobject != null && instance.GetType() != baseobject.GetType()) { obj = baseobject; } XamlObject xamlobj = (XamlObject)CreatePropertyValue(obj, null); xamlobj.Instance = instance; return(xamlobj); }
bool UpdateXmlAttribute(bool force, out XamlObject holder) { holder = FindXmlAttributeHolder(); if (holder == null && force && IsMarkupExtension) { holder = this; } if (holder != null && MarkupExtensionPrinter.CanPrint(holder)) { var s = MarkupExtensionPrinter.Print(holder); holder.XmlAttribute = holder.ParentProperty.SetAttribute(s); return(true); } return(false); }
internal XamlProperty(XamlObject parentObject, XamlPropertyInfo propertyInfo) { this.parentObject = parentObject; this.propertyInfo = propertyInfo; if (propertyInfo.IsCollection) { isCollection = true; collectionElements = new CollectionElementsCollection(this); if (propertyInfo.Name.Equals(XamlConstants.ResourcesPropertyName, StringComparison.Ordinal) && propertyInfo.ReturnType == typeof(ResourceDictionary)) { isResources = true; } } }
/// <summary> /// Gets whether shorthand XAML markup extension code can be generated for the object. /// </summary> public static bool CanPrint(XamlObject obj) { if (obj.ElementType == typeof(System.Windows.Data.MultiBinding) || obj.ElementType == typeof(System.Windows.Data.PriorityBinding)) { return(false); } foreach (var property in obj.Properties.Where((prop) => prop.IsSet)) { var value = property.PropertyValue; if (value is XamlTextValue) { continue; } else { XamlObject xamlObject = value as XamlObject; if (xamlObject == null || !xamlObject.IsMarkupExtension) { return(false); } else { var staticResource = xamlObject.Instance as System.Windows.StaticResourceExtension; if (staticResource != null && staticResource.ResourceKey != null) { XamlObject parent = GetNonMarkupExtensionParent(xamlObject); if (parent != null) { var parentLocalResource = parent.ServiceProvider.Resolver.FindLocalResource(staticResource.ResourceKey); // If resource with the specified key is declared locally on the same object as the StaticResource is being used the markup extension // must be printed as element to find the resource, otherwise it will search from parent-parent and find none or another resource. if (parentLocalResource != null) { return(false); } } } } } } return(true); }
/// <summary> /// Gets the type descriptor context used for type conversions. /// </summary> /// <param name="containingObject">The containing object, used when the /// type descriptor context needs to resolve an XML namespace.</param> internal ITypeDescriptorContext GetTypeDescriptorContext(XamlObject containingObject) { IServiceProvider serviceProvider; if (containingObject != null) { if (containingObject.OwnerDocument != this) { throw new ArgumentException("Containing object must belong to the document!"); } serviceProvider = containingObject.ServiceProvider; } else { serviceProvider = this.ServiceProvider; } return(new DummyTypeDescriptorContext(serviceProvider)); }
private static bool IsStaticResourceThatReferencesLocalResource(XamlObject obj, XamlObject nonMarkupExtensionParent) { var staticResource = obj.Instance as System.Windows.StaticResourceExtension; if (staticResource != null && staticResource.ResourceKey != null && nonMarkupExtensionParent != null) { var parentLocalResource = nonMarkupExtensionParent.ServiceProvider.Resolver.FindLocalResource(staticResource.ResourceKey); // If resource with the specified key is declared locally on the same object as the StaticResource is being used the markup extension // must be printed as element to find the resource, otherwise it will search from parent-parent and find none or another resource. if (parentLocalResource != null) { return(true); } } return(false); }
/// <summary> /// Finds the XAML namescope for the specified object and uses it to unregister the old name and then register the new name. /// </summary> /// <param name="namedObject">The object where the name was changed.</param> /// <param name="oldName">The old name.</param> /// <param name="newName">The new name.</param> public static void NameChanged(XamlObject namedObject, string oldName, string newName) { var obj = namedObject; while (obj != null) { var nameScope = obj.Instance as INameScope; if (nameScope == null) { var depObj = obj.Instance as DependencyObject; if (depObj != null) { nameScope = NameScope.GetNameScope(depObj); } } if (nameScope != null) { if (oldName != null) { try { nameScope.UnregisterName(oldName); } catch (Exception x) { Debug.WriteLine(x.Message); } } if (newName != null) { nameScope.RegisterName(newName, namedObject.Instance); try{ var prp = namedObject.ElementType.GetProperty(namedObject.RuntimeNameProperty); if (prp != null) { prp.SetValue(namedObject.Instance, newName, null); } } catch (Exception x) { Debug.WriteLine(x.Message); } } break; } obj = obj.ParentObject; } }
public object FindResource(object key) { XamlObject obj = containingObject; while (obj != null) { FrameworkElement el = obj.Instance as FrameworkElement; if (el != null) { object val = el.Resources[key]; if (val != null) { return(val); } } obj = obj.ParentObject; } return(null); }
/// <summary> /// Generates XAML markup extension code for the object. /// </summary> public static string Print(XamlObject obj) { StringBuilder sb = new StringBuilder(); sb.Append("{"); sb.Append(obj.GetNameForMarkupExtension()); bool first = true; foreach (var property in obj.Properties) { if (!property.IsSet) { continue; } if (first) { sb.Append(" "); } else { sb.Append(", "); } first = false; sb.Append(property.GetNameForMarkupExtension()); sb.Append("="); var value = property.PropertyValue; if (value is XamlTextValue) { sb.Append((value as XamlTextValue).Text); } else if (value is XamlObject) { sb.Append(Print(value as XamlObject)); } } sb.Append("}"); return(sb.ToString()); }
/// <summary> /// Generates XAML markup extension code for the object. /// </summary> public static string Print(XamlObject obj) { StringBuilder sb = new StringBuilder(); sb.Append("{"); sb.Append(obj.GetNameForMarkupExtension()); bool first = true; foreach (var property in obj.Properties) { if (!property.IsSet) continue; if (first) sb.Append(" "); else sb.Append(", "); first = false; sb.Append(property.GetNameForMarkupExtension()); sb.Append("="); var value = property.PropertyValue; var textValue = value as XamlTextValue; if (textValue != null) { string text = textValue.Text; bool containsSpace = text.Contains(' '); if(containsSpace) { sb.Append('\''); } sb.Append(text.Replace("\\", "\\\\")); if(containsSpace) { sb.Append('\''); } } else if (value is XamlObject) { sb.Append(Print(value as XamlObject)); } } sb.Append("}"); return sb.ToString(); }
public XamlPropertyInfo ResolveProperty(string propertyName) { string propertyNamespace; if (propertyName.Contains(":")) { propertyNamespace = ContainingElement.GetNamespaceOfPrefix(propertyName.Substring(0, propertyName.IndexOf(':'))); propertyName = propertyName.Substring(propertyName.IndexOf(':') + 1); } else { propertyNamespace = ContainingElement.GetNamespaceOfPrefix(""); } Type elementType = null; XamlObject obj = containingObject; while (obj != null) { Style style = obj.Instance as Style; if (style != null && style.TargetType != null) { elementType = style.TargetType; break; } obj = obj.ParentObject; } if (propertyName.Contains(".")) { var allPropertiesAllowed = this.containingObject is XamlObject && (((XamlObject)this.containingObject).ElementType == typeof(Setter) || ((XamlObject)this.containingObject).IsMarkupExtension); return(XamlParser.GetPropertyInfo(document.TypeFinder, null, elementType, propertyNamespace, propertyName, allPropertiesAllowed)); } else if (elementType != null) { return(XamlParser.FindProperty(null, elementType, propertyName)); } else { return(null); } }
public XamlPropertyInfo ResolveProperty(string propertyName) { string propertyNamespace; if (propertyName.Contains(":")) { propertyNamespace = ContainingElement.GetNamespaceOfPrefix(propertyName.Substring(0, propertyName.IndexOf(':'))); propertyName = propertyName.Substring(propertyName.IndexOf(':') + 1); } else { propertyNamespace = ContainingElement.GetNamespaceOfPrefix(""); } Type elementType = null; XamlObject obj = containingObject; while (obj != null) { Style style = obj.Instance as Style; if (style != null && style.TargetType != null) { elementType = style.TargetType; break; } obj = obj.ParentObject; } if (propertyName.Contains(".")) { return(XamlParser.GetPropertyInfo(document.TypeFinder, null, elementType, propertyNamespace, propertyName)); } else if (elementType != null) { return(XamlParser.FindProperty(null, elementType, propertyName)); } else { return(null); } }
/// <summary> /// Gets whether shorthand XAML markup extension code can be generated for the object. /// </summary> public static bool CanPrint(XamlObject obj) { if (obj.ElementType == typeof(System.Windows.Data.MultiBinding) || obj.ElementType == typeof(System.Windows.Data.PriorityBinding)) { return false; } foreach (var property in obj.Properties.Where((prop) => prop.IsSet)) { var value = property.PropertyValue; if (value is XamlTextValue) continue; else { XamlObject xamlObject = value as XamlObject; if (xamlObject == null || !xamlObject.IsMarkupExtension) return false; else { var staticResource = xamlObject.Instance as System.Windows.StaticResourceExtension; if (staticResource != null && staticResource.ResourceKey != null) { XamlObject parent = GetNonMarkupExtensionParent(xamlObject); if (parent != null) { var parentLocalResource = parent.ServiceProvider.Resolver.FindLocalResource(staticResource.ResourceKey); // If resource with the specified key is declared locally on the same object as the StaticResource is being used the markup extension // must be printed as element to find the resource, otherwise it will search from parent-parent and find none or another resource. if (parentLocalResource != null) return false; } } } } } return true; }
/// <summary> /// Gets the XAML namescope for the specified object. /// </summary> /// <param name="obj">The object to get the XAML namescope for.</param> /// <returns>A XAML namescope, as an <see cref="INameScope"/> instance.</returns> public static INameScope GetNameScopeFromObject(XamlObject obj) { INameScope nameScope = null; while (obj != null) { nameScope = obj.Instance as INameScope; if (nameScope == null) { var xamlObj = obj.ParentObject != null ? obj.ParentObject : obj; var depObj = xamlObj.Instance as DependencyObject; if (depObj != null) nameScope = NameScope.GetNameScope(depObj); if (nameScope != null) break; } obj = obj.ParentObject; } return nameScope; }
/// <summary> /// Removes namespace attributes defined in the root from the specified node and all child nodes. /// </summary> static void RemoveRootNamespacesFromNodeAndChildNodes(XamlObject root, XmlNode node) { foreach (XmlNode childNode in node.ChildNodes) { RemoveRootNamespacesFromNodeAndChildNodes(root, childNode); } if (node.Attributes != null) { List <XmlAttribute> removeAttributes = new List <XmlAttribute>(); foreach (XmlAttribute attrib in node.Attributes) { if (attrib.Name.StartsWith("xmlns:")) { var rootPrefix = root.OwnerDocument.GetPrefixForNamespace(attrib.Value); if (rootPrefix == null) { //todo: check if we can add to root, (maybe same ns exists) root.OwnerDocument.XmlDocument.Attributes.Append((XmlAttribute)attrib.CloneNode(true)); removeAttributes.Add(attrib); } else if (rootPrefix == attrib.Name.Substring("xmlns:".Length)) { removeAttributes.Add(attrib); } } else if (attrib.Name == "xmlns" && attrib.Value == XamlConstants.PresentationNamespace) { removeAttributes.Add(attrib); } } foreach (var removeAttribute in removeAttributes) { node.Attributes.Remove(removeAttribute); } } }
/// <summary> /// Method use to parse a piece of Xaml. /// </summary> /// <param name="root">The Root XamlObject of the current document.</param> /// <param name="xaml">The Xaml being parsed.</param> /// <param name="settings">Parser settings used by <see cref="XamlParser"/>.</param> /// <param name="parentObject">Parent Object, where the Parsed snippet will be inserted (Needed for Example for Bindings).</param> /// <returns>Returns the XamlObject of the parsed <paramref name="xaml"/>.</returns> public static XamlObject ParseSnippet(XamlObject root, string xaml, XamlParserSettings settings, XamlObject parentObject) { XmlTextReader reader = new XmlTextReader(new StringReader(xaml)); var element = root.OwnerDocument.XmlDocument.ReadNode(reader); if (element != null) { XmlAttribute xmlnsAttribute = null; foreach (XmlAttribute attrib in element.Attributes) { if (attrib.Name == "xmlns") { xmlnsAttribute = attrib; } } if (xmlnsAttribute != null) { element.Attributes.Remove(xmlnsAttribute); } XamlParser parser = new XamlParser(); parser.settings = settings; parser.errorSink = (IXamlErrorSink)settings.ServiceProvider.GetService(typeof(IXamlErrorSink)); parser.document = root.OwnerDocument; parser.currentXamlObject = parentObject; var xamlObject = parser.ParseObject(element as XmlElement); RemoveRootNamespacesFromNodeAndChildNodes(root, element); if (xamlObject != null) { return(xamlObject); } } return(null); }
internal static object CreateObjectFromAttributeText(string valueText, XamlPropertyInfo targetProperty, XamlObject scope) { return(targetProperty.TypeConverter.ConvertFromString( scope.OwnerDocument.GetTypeDescriptorContext(scope), CultureInfo.InvariantCulture, valueText)); }
void ParseObjectChildElementAsPropertyElement(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty) { Debug.Assert(element.LocalName.Contains(".")); // this is a element property syntax XamlPropertyInfo propertyInfo = GetPropertyInfo(settings.TypeFinder, obj.Instance, obj.ElementType, element.NamespaceURI, element.LocalName); bool valueWasSet = false; object collectionInstance = null; bool isElementChildACollectionForProperty = false; XamlProperty collectionProperty = null; if (propertyInfo.IsCollection) { if (defaultProperty != null && defaultProperty.FullyQualifiedName == propertyInfo.FullyQualifiedName) { foreach (XamlProperty existing in obj.Properties) { if (existing.propertyInfo == defaultProperty) { collectionProperty = existing; break; } } } if (collectionProperty == null) { obj.AddProperty(collectionProperty = new XamlProperty(obj, propertyInfo)); } isElementChildACollectionForProperty = IsElementChildACollectionForProperty(settings.TypeFinder, element, propertyInfo); if (isElementChildACollectionForProperty) { collectionProperty.ParserSetPropertyElement((XmlElement)element.FirstChild); } else { collectionInstance = collectionProperty.propertyInfo.GetValue(obj.Instance); collectionProperty.ParserSetPropertyElement(element); } } XmlSpace oldXmlSpace = currentXmlSpace; if (element.HasAttribute("xml:space")) { currentXmlSpace = (XmlSpace)Enum.Parse(typeof(XmlSpace), element.GetAttribute("xml:space"), true); } foreach (XmlNode childNode in element.ChildNodes) { XamlPropertyValue childValue = ParseValue(childNode); if (childValue != null) { if (propertyInfo.IsCollection) { if (isElementChildACollectionForProperty) { collectionProperty.PropertyValue = childValue; } else { CollectionSupport.AddToCollection(propertyInfo.ReturnType, collectionInstance, childValue); collectionProperty.ParserAddCollectionElement(element, childValue); } } else { if (valueWasSet) { throw new XamlLoadException("non-collection property may have only one child element"); } valueWasSet = true; XamlProperty xp = new XamlProperty(obj, propertyInfo, childValue); xp.ParserSetPropertyElement(element); obj.AddProperty(xp); } } } currentXmlSpace = oldXmlSpace; }
void ParseObjectContent(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty, XamlTextValue initializeFromTextValueInsteadOfConstructor) { bool isDefaultValueSet = false; XamlProperty collectionProperty = null; object collectionInstance = null; Type collectionType = null; XmlElement collectionPropertyElement = null; var elementChildNodes = GetNormalizedChildNodes(element); if (defaultProperty == null && obj.Instance != null && CollectionSupport.IsCollectionType(obj.Instance.GetType())) { XamlObject parentObj = obj.ParentObject; var parentElement = element.ParentNode; XamlPropertyInfo propertyInfo = GetPropertyInfo(settings.TypeFinder, parentObj.Instance, parentObj.ElementType, parentElement.NamespaceURI, parentElement.LocalName); collectionProperty = FindExistingXamlProperty(parentObj, propertyInfo); collectionInstance = obj.Instance; collectionType = obj.ElementType; collectionPropertyElement = element; } else if (defaultProperty != null && defaultProperty.IsCollection && !element.IsEmpty) { foreach (XmlNode childNode in elementChildNodes) { XmlElement childElement = childNode as XmlElement; if (childElement == null || !ObjectChildElementIsPropertyElement(childElement)) { obj.AddProperty(collectionProperty = new XamlProperty(obj, defaultProperty)); collectionType = defaultProperty.ReturnType; collectionInstance = defaultProperty.GetValue(obj.Instance); break; } } } foreach (XmlNode childNode in elementChildNodes) { XmlElement childElement = childNode as XmlElement; if (childElement != null) { if (childElement.NamespaceURI == XamlConstants.XamlNamespace) { continue; } if (ObjectChildElementIsPropertyElement(childElement)) { ParseObjectChildElementAsPropertyElement(obj, childElement, defaultProperty); continue; } } if (initializeFromTextValueInsteadOfConstructor != null) { continue; } XamlPropertyValue childValue = ParseValue(childNode); if (childValue != null) { if (collectionProperty != null) { collectionProperty.ParserAddCollectionElement(collectionPropertyElement, childValue); CollectionSupport.AddToCollection(collectionType, collectionInstance, childValue); } else { if (defaultProperty == null) { throw new XamlLoadException("This element does not have a default value, cannot assign to it"); } if (isDefaultValueSet) { throw new XamlLoadException("default property may have only one value assigned"); } obj.AddProperty(new XamlProperty(obj, defaultProperty, childValue)); isDefaultValueSet = true; } } } }
public XamlDesignItem(XamlObject xamlObject, XamlDesignContext designContext) { this._xamlObject = xamlObject; this._designContext = designContext; this._properties = new XamlModelPropertyCollection(this); }
XamlObject ParseObject(XmlElement element) { Type elementType = settings.TypeFinder.GetType(element.NamespaceURI, element.LocalName); if (elementType == null) { elementType = settings.TypeFinder.GetType(element.NamespaceURI, element.LocalName + "Extension"); if (elementType == null) { throw new XamlLoadException("Cannot find type " + element.Name); } } XmlSpace oldXmlSpace = currentXmlSpace; XamlObject parentXamlObject = currentXamlObject; if (element.HasAttribute("xml:space")) { currentXmlSpace = (XmlSpace)Enum.Parse(typeof(XmlSpace), element.GetAttribute("xml:space"), true); } XamlPropertyInfo defaultProperty = GetDefaultProperty(elementType); XamlTextValue initializeFromTextValueInsteadOfConstructor = null; if (defaultProperty == null) { int numberOfTextNodes = 0; bool onlyTextNodes = true; foreach (XmlNode childNode in element.ChildNodes) { if (childNode.NodeType == XmlNodeType.Text) { numberOfTextNodes++; } else if (childNode.NodeType == XmlNodeType.Element) { onlyTextNodes = false; } } if (onlyTextNodes && numberOfTextNodes == 1) { foreach (XmlNode childNode in element.ChildNodes) { if (childNode.NodeType == XmlNodeType.Text) { initializeFromTextValueInsteadOfConstructor = (XamlTextValue)ParseValue(childNode); } } } } object instance; if (initializeFromTextValueInsteadOfConstructor != null) { instance = TypeDescriptor.GetConverter(elementType).ConvertFromString( document.GetTypeDescriptorContext(null), CultureInfo.InvariantCulture, initializeFromTextValueInsteadOfConstructor.Text); } else { instance = settings.CreateInstanceCallback(elementType, emptyObjectArray); } XamlObject obj = new XamlObject(document, element, elementType, instance); currentXamlObject = obj; obj.ParentObject = parentXamlObject; if (parentXamlObject == null && obj.Instance is DependencyObject) { NameScope.SetNameScope((DependencyObject)obj.Instance, new NameScope()); } ISupportInitialize iSupportInitializeInstance = instance as ISupportInitialize; if (iSupportInitializeInstance != null) { iSupportInitializeInstance.BeginInit(); } foreach (XmlAttribute attribute in element.Attributes) { if (attribute.Value.StartsWith("clr-namespace", StringComparison.OrdinalIgnoreCase)) { // the format is "clr-namespace:<Namespace here>;assembly=<Assembly name here>" var clrNamespace = attribute.Value.Split(new[] { ':', ';', '=' }); if (clrNamespace.Length == 4) { // get the assembly name var assembly = settings.TypeFinder.LoadAssembly(clrNamespace[3]); if (assembly != null) { settings.TypeFinder.RegisterAssembly(assembly); } } else { // if no assembly name is there, then load the assembly of the opened file. var assembly = settings.TypeFinder.LoadAssembly(null); if (assembly != null) { settings.TypeFinder.RegisterAssembly(assembly); } } } if (attribute.NamespaceURI == XamlConstants.XmlnsNamespace) { continue; } if (attribute.Name == "xml:space") { continue; } if (GetAttributeNamespace(attribute) == XamlConstants.XamlNamespace) { if (attribute.LocalName == "Name") { try { NameScopeHelper.NameChanged(obj, null, attribute.Value); } catch (Exception x) { ReportException(x, attribute); } } continue; } ParseObjectAttribute(obj, attribute); } if (!(obj.Instance is Style)) { ParseObjectContent(obj, element, defaultProperty, initializeFromTextValueInsteadOfConstructor); } if (iSupportInitializeInstance != null) { iSupportInitializeInstance.EndInit(); } currentXmlSpace = oldXmlSpace; currentXamlObject = parentXamlObject; return(obj); }
/// <summary> /// Method use to parse a piece of Xaml. /// </summary> /// <param name="root">The Root XamlObject of the current document.</param> /// <param name="xaml">The Xaml being parsed.</param> /// <param name="settings">Parser settings used by <see cref="XamlParser"/>.</param> /// <param name="parentObject">Parent Object, where the Parsed snippet will be inserted (Needed for Example for Bindings).</param> /// <returns>Returns the XamlObject of the parsed <paramref name="xaml"/>.</returns> public static XamlObject ParseSnippet(XamlObject root, string xaml, XamlParserSettings settings, XamlObject parentObject) { XmlTextReader reader = new XmlTextReader(new StringReader(xaml)); var element = root.OwnerDocument.XmlDocument.ReadNode(reader); if (element != null) { XmlAttribute xmlnsAttribute=null; foreach (XmlAttribute attrib in element.Attributes) { if (attrib.Name == "xmlns") xmlnsAttribute = attrib; } if(xmlnsAttribute!=null) element.Attributes.Remove(xmlnsAttribute); XamlParser parser = new XamlParser(); parser.settings = settings; parser.errorSink = (IXamlErrorSink)settings.ServiceProvider.GetService(typeof(IXamlErrorSink)); parser.document = root.OwnerDocument; parser.currentXamlObject = parentObject; var xamlObject = parser.ParseObject(element as XmlElement); RemoveRootNamespacesFromNodeAndChildNodes(root, element); if (xamlObject != null) return xamlObject; } return null; }
private static XamlObject GetNonMarkupExtensionParent(XamlObject markupExtensionObject) { System.Diagnostics.Debug.Assert(markupExtensionObject.IsMarkupExtension); XamlObject obj = markupExtensionObject; while (obj != null && obj.IsMarkupExtension) { obj = obj.ParentObject; } return obj; }
internal override void OnParentPropertyChanged() { parentObject = (ParentProperty != null) ? ParentProperty.ParentObject : null; base.OnParentPropertyChanged(); }
private static bool CanPrint(XamlObject obj, bool isNested, XamlObject nonMarkupExtensionParent) { if ((isNested || obj.ParentObject == nonMarkupExtensionParent) && IsStaticResourceThatReferencesLocalResource(obj, nonMarkupExtensionParent)) { return false; } foreach (var property in obj.Properties.Where((prop) => prop.IsSet)) { var value = property.PropertyValue; if (value is XamlTextValue) continue; else { var xamlObject = value as XamlObject; if (xamlObject == null || !xamlObject.IsMarkupExtension) return false; else if (!CanPrint(xamlObject, true, nonMarkupExtensionParent)) return false; } } return true; }
/// <summary> /// Called by XamlParser to finish initializing the document. /// </summary> internal void ParseComplete(XamlObject rootElement) { this._rootElement = rootElement; }
/// <summary> /// Removes namespace attributes defined in the root from the specified node and all child nodes. /// </summary> static void RemoveRootNamespacesFromNodeAndChildNodes(XamlObject root, XmlNode node) { foreach (XmlNode childNode in node.ChildNodes) { RemoveRootNamespacesFromNodeAndChildNodes(root, childNode); } if (node.Attributes != null) { List<XmlAttribute> removeAttributes = new List<XmlAttribute>(); foreach (XmlAttribute attrib in node.Attributes) { if (attrib.Name.StartsWith("xmlns:")) { var rootPrefix = root.OwnerDocument.GetPrefixForNamespace(attrib.Value); if (rootPrefix == null) { //todo: check if we can add to root, (maybe same ns exists) root.OwnerDocument.XmlDocument.Attributes.Append((XmlAttribute)attrib.CloneNode(true)); removeAttributes.Add(attrib); } else if (rootPrefix == attrib.Name.Substring("xmlns:".Length)) { removeAttributes.Add(attrib); } } else if (attrib.Name == "xmlns" && attrib.Value == XamlConstants.PresentationNamespace) { removeAttributes.Add(attrib); } } foreach (var removeAttribute in removeAttributes) { node.Attributes.Remove(removeAttribute); } } }
internal static object CreateObjectFromAttributeText(string valueText, Type targetType, XamlObject scope) { var converter = XamlNormalPropertyInfo.GetCustomTypeConverter(targetType) ?? TypeDescriptor.GetConverter(targetType); return(converter.ConvertFromInvariantString( scope.OwnerDocument.GetTypeDescriptorContext(scope), valueText)); }
/// <summary> /// Get's all Child XamlObject Instances /// </summary> /// <param name="item"></param> /// <param name="onlyFromSameNamescope"></param> /// <returns></returns> private IEnumerable<XamlObject> GetAllChildXamlObjects(XamlObject item, bool onlyFromSameNamescope = false) { foreach (var prop in item.Properties) { if (prop.PropertyValue as XamlObject != null) { if (!onlyFromSameNamescope || NameScopeHelper.GetNameScopeFromObject(item) == NameScopeHelper.GetNameScopeFromObject(prop.PropertyValue as XamlObject)) yield return prop.PropertyValue as XamlObject; foreach (var i in GetAllChildXamlObjects(prop.PropertyValue as XamlObject)) { if (!onlyFromSameNamescope || NameScopeHelper.GetNameScopeFromObject(item) == NameScopeHelper.GetNameScopeFromObject(i)) yield return i; } } if (prop.IsCollection) { foreach (var collectionElement in prop.CollectionElements) { if (collectionElement as XamlObject != null) { if (!onlyFromSameNamescope || NameScopeHelper.GetNameScopeFromObject(item) == NameScopeHelper.GetNameScopeFromObject(collectionElement as XamlObject)) yield return collectionElement as XamlObject; foreach (var i in GetAllChildXamlObjects(collectionElement as XamlObject)) { if (!onlyFromSameNamescope || NameScopeHelper.GetNameScopeFromObject(item) == NameScopeHelper.GetNameScopeFromObject(i)) yield return i; } } } } } }
internal static object CreateObjectFromAttributeText(string valueText, XamlPropertyInfo targetProperty, XamlObject scope) { if (targetProperty.ReturnType == typeof(Uri)) { return scope.OwnerDocument.TypeFinder.ConvertUriToLocalUri(new Uri(valueText, UriKind.RelativeOrAbsolute)); } else if (targetProperty.ReturnType == typeof(ImageSource)) { var uri = scope.OwnerDocument.TypeFinder.ConvertUriToLocalUri(new Uri(valueText, UriKind.RelativeOrAbsolute)); return targetProperty.TypeConverter.ConvertFromString(scope.OwnerDocument.GetTypeDescriptorContext(scope), CultureInfo.InvariantCulture, uri.ToString()); } return targetProperty.TypeConverter.ConvertFromString( scope.OwnerDocument.GetTypeDescriptorContext(scope), CultureInfo.InvariantCulture, valueText); }
/// <summary> /// Method use to parse a piece of Xaml. /// </summary> /// <param name="root">The Root XamlObject of the current document.</param> /// <param name="xaml">The Xaml being parsed.</param> /// <param name="settings">Parser settings used by <see cref="XamlParser"/>.</param> /// <returns>Returns the XamlObject of the parsed <paramref name="xaml"/>.</returns> public static XamlObject ParseSnippet(XamlObject root, string xaml, XamlParserSettings settings) { return ParseSnippet(root, xaml, settings, null); }
/// <summary> /// Find's the Root XamlObject (real Root, or Root Object in Namescope) /// </summary> /// <param name="item"></param> /// <param name="onlyFromSameNamescope"></param> /// <returns></returns> private XamlObject GetRootXamlObject(XamlObject item, bool onlyFromSameNamescope = false) { var root = item; while (root.ParentObject != null) { if (onlyFromSameNamescope && NameScopeHelper.GetNameScopeFromObject(root) != NameScopeHelper.GetNameScopeFromObject(root.ParentObject)) break; root = root.ParentObject; } return root; }
bool UpdateXmlAttribute(bool force, out XamlObject holder) { holder = FindXmlAttributeHolder(); if (holder == null && force && IsMarkupExtension) { holder = this; } if (holder != null && MarkupExtensionPrinter.CanPrint(holder)) { var s = MarkupExtensionPrinter.Print(holder); holder.XmlAttribute = holder.ParentProperty.SetAttribute(s); return true; } return false; }
internal static object CreateObjectFromAttributeText(string valueText, Type targetType, XamlObject scope) { var converter = XamlNormalPropertyInfo.GetCustomTypeConverter(targetType) ?? TypeDescriptor.GetConverter(targetType); return converter.ConvertFromInvariantString( scope.OwnerDocument.GetTypeDescriptorContext(scope), valueText); }
private static bool IsStaticResourceThatReferencesLocalResource(XamlObject obj, XamlObject nonMarkupExtensionParent) { var staticResource = obj.Instance as System.Windows.StaticResourceExtension; if (staticResource != null && staticResource.ResourceKey != null && nonMarkupExtensionParent != null) { var parentLocalResource = nonMarkupExtensionParent.ServiceProvider.Resolver.FindLocalResource(staticResource.ResourceKey); // If resource with the specified key is declared locally on the same object as the StaticResource is being used the markup extension // must be printed as element to find the resource, otherwise it will search from parent-parent and find none or another resource. if (parentLocalResource != null) return true; } return false; }