Beispiel #1
0
        internal static void ParseObjectAttribute(XamlObject obj, XmlAttribute attribute, bool real)
        {
            XamlPropertyInfo propertyInfo = GetPropertyInfo(obj.Instance, obj.ElementType, attribute,
                                                            obj.OwnerDocument.TypeFinder);
            XamlPropertyValue value = null;

            var valueText = attribute.Value;

            if (valueText.StartsWith("{", StringComparison.Ordinal) &&
                !valueText.StartsWith("{}", StringComparison.Ordinal))
            {
                var xamlObject = MarkupExtensionParser.Parse(valueText, obj, real ? attribute : null);
                value = xamlObject;
            }
            else
            {
                if (real)
                {
                    value = new XamlTextValue(obj.OwnerDocument, attribute);
                }
                else
                {
                    value = new XamlTextValue(obj.OwnerDocument, valueText);
                }
            }

            var property = new XamlProperty(obj, propertyInfo, value);

            obj.AddProperty(property);
        }
Beispiel #2
0
        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.ChildNodes.Cast <XmlNode>()
                                                                .Where(x => !(x is XmlWhitespace))
                                                                .First());
                }
                else
                {
                    collectionInstance = collectionProperty.propertyInfo.GetValue(obj.Instance);
                    collectionProperty.ParserSetPropertyElement(element);
                    collectionInstance = collectionInstance ??
                                         Activator.CreateInstance(collectionProperty.propertyInfo.ReturnType);
                }
            }

            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)
            {
                currentParsedNode = childNode;
                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);
                    }
                }
            }

            currentParsedNode = element;

            currentXmlSpace = oldXmlSpace;
        }
Beispiel #3
0
        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;
                if (parentObj != null)
                {
                    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)
                {
                    currentParsedNode = childNode;
                    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;
                    }
                }
            }

            currentParsedNode = element;

            if (collectionType != null && collectionInstance == null && elementChildNodes.Count() == 1)
            {
                var firstChild = elementChildNodes.First() as XmlElement;
                if (ObjectChildElementIsCollectionInstance(firstChild, collectionType))
                {
                    collectionInstance = ParseObject(firstChild);
                    collectionProperty.PropertyValue = (XamlPropertyValue)collectionInstance;
                }
                else
                {
                    throw new XamlLoadException("Collection Instance is null");
                }
            }
            else
            {
                foreach (XmlNode childNode in elementChildNodes)
                {
                    currentParsedNode = childNode;
                    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 (collectionProperty == null && collectionInstance is ResourceDictionary)
                        {
                            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;
                        }
                    }
                }
            }

            currentParsedNode = element;
        }