void PossiblyNameChanged(XamlPropertyValue oldValue, XamlPropertyValue newValue) { if (ParentObject.RuntimeNameProperty != null && PropertyName == ParentObject.RuntimeNameProperty) { if (!String.IsNullOrEmpty(ParentObject.GetXamlAttribute("Name"))) { throw new XamlLoadException("The property 'Name' is set more than once."); } string oldName = null; string newName = null; var oldTextValue = oldValue as XamlTextValue; if (oldTextValue != null) { oldName = oldTextValue.Text; } var newTextValue = newValue as XamlTextValue; if (newTextValue != null) { newName = newTextValue.Text; } NameScopeHelper.NameChanged(ParentObject, oldName, newName); } }
/// <inheritdoc/> public object Resolve(string name) { INameScope ns = null; var xamlObj = this.XamlObject; while (xamlObj != null) { ns = NameScopeHelper.GetNameScopeFromObject(xamlObj); if (ns != null) { var obj = ns.FindName(name); if (obj != null) { return(obj); } } xamlObj = xamlObj.ParentObject; } return(null); }
/// <summary> /// Sets an attribute in the x:-namespace. /// </summary> public void SetXamlAttribute(string name, string value) { XamlProperty runtimeNameProperty = null; bool isNameChange = false; if (name == "Name") { isNameChange = true; string oldName = GetXamlAttribute("Name"); if (String.IsNullOrEmpty(oldName)) { runtimeNameProperty = this.NameProperty; if (runtimeNameProperty != null) { if (runtimeNameProperty.IsSet) { oldName = (string)runtimeNameProperty.ValueOnInstance; } else { runtimeNameProperty = null; } } } if (String.IsNullOrEmpty(oldName)) { oldName = null; } NameScopeHelper.NameChanged(this, oldName, value); } if (value == null) { element.RemoveAttribute(name, XamlConstants.XamlNamespace); } else { var prefix = element.GetPrefixOfNamespace(XamlConstants.XamlNamespace); var prefix2009 = element.GetPrefixOfNamespace(XamlConstants.Xaml2009Namespace); if (!string.IsNullOrEmpty(prefix)) { var attribute = element.OwnerDocument.CreateAttribute(prefix, name, XamlConstants.XamlNamespace); attribute.InnerText = value; element.SetAttributeNode(attribute); } else if (!string.IsNullOrEmpty(prefix2009)) { var attribute = element.OwnerDocument.CreateAttribute(prefix, name, XamlConstants.Xaml2009Namespace); attribute.InnerText = value; element.SetAttributeNode(attribute); } else { element.SetAttribute(name, XamlConstants.XamlNamespace, value); } } if (isNameChange) { bool nameChangedAlreadyRaised = false; if (runtimeNameProperty != null) { var handler = new EventHandler((sender, e) => nameChangedAlreadyRaised = true); this.NameChanged += handler; try { runtimeNameProperty.Reset(); } finally { this.NameChanged -= handler; } } if (NameChanged != null && !nameChangedAlreadyRaised) { NameChanged(this, EventArgs.Empty); } } }
XamlObject ParseObject(XmlElement element) { Type elementType = settings.TypeFinder.GetType(element.NamespaceURI, element.LocalName); if (typeof(FrameworkTemplate).IsAssignableFrom(elementType)) { var xamlObj = new XamlObject(document, element, elementType, TemplateHelper.GetFrameworkTemplate(element, currentXamlObject)); xamlObj.ParentObject = currentXamlObject; return(xamlObj); } 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 (elementType == typeof(string) && numberOfTextNodes == 0) { initializeFromTextValueInsteadOfConstructor = new XamlTextValue(document, string.Empty); } else if (onlyTextNodes && numberOfTextNodes == 1) { foreach (XmlNode childNode in element.ChildNodes) { if (childNode.NodeType == XmlNodeType.Text) { currentParsedNode = childNode; initializeFromTextValueInsteadOfConstructor = (XamlTextValue)ParseValue(childNode); } } } } currentParsedNode = element; 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 || GetAttributeNamespace(attribute) == XamlConstants.Xaml2009Namespace) { if (attribute.LocalName == "Name") { try { NameScopeHelper.NameChanged(obj, null, attribute.Value); } catch (Exception x) { ReportException(x, attribute); } } continue; } ParseObjectAttribute(obj, attribute); } ParseObjectContent(obj, element, defaultProperty, initializeFromTextValueInsteadOfConstructor); if (iSupportInitializeInstance != null) { iSupportInitializeInstance.EndInit(); } currentXmlSpace = oldXmlSpace; currentXamlObject = parentXamlObject; return(obj); }