Exemplo n.º 1
0
        /// <summary>
        /// Converts the specified <paramref name="obj"/> to a collection.
        /// If the object supports the interface <see cref="ICollection"/> itself,
        /// it will simply be casted. If it is an <see cref="IEnumerable"/>, its contents
        /// will be copied into a new object implementing <see cref="ICollection"/>.
        /// Else, a new <see cref="ICollection"/> will be created with <paramref name="obj"/>
        /// as single contents.
        /// A string won't be treated as a collection of characters but will be treated as if
        /// it was no collection.
        /// </summary>
        /// <param name="obj">The object to convert to a collection.</param>
        /// <param name="entryType">Type to convert the collection entries to or <c>null</c>.</param>
        /// <param name="result">Collection containing the contents of obj or obj itself.</param>
        /// <returns><c>true</c>, if the conversion was successful, else <c>false</c>.</returns>
        protected static bool ToCollection(object obj, Type entryType, out ICollection result)
        {
            obj = ParserHelper.UnwrapIncludesAndCleanup(obj);
            if (obj.GetType() != typeof(string)) // Don't treat strings as a collection of characters
            {
                if (obj is ICollection)
                {
                    return(ConvertEntryType((ICollection)obj, entryType, out result));
                }
                if (obj is IEnumerable)
                {
                    List <object> col = ((IEnumerable)obj).Cast <object>().ToList();
                    return(ConvertEntryType(col, entryType, out result));
                }
            }
            List <object> res = new List <object>();
            object        o2;

            if (entryType == null)
            {
                res.Add(obj);
            }
            else if (Convert(obj, entryType, out o2))
            {
                res.Add(o2);
            }
            else
            {
                result = null;
                return(false);
            }
            result = res;
            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Parses the XAML file associated with this parser.
        /// </summary>
        /// <returns>The visual corresponding to the root XAML element.</returns>
        public object Parse()
        {
            if (_rootObject != null)
            {
                throw new XamlParserException("XAML Parser: Parse() method was invoked multiple times");
            }
            object key;

            _rootObject = ParserHelper.UnwrapIncludesAndCleanup(Instantiate(_xmlDocument.DocumentElement, out key));
            if (key != null)
            {
                throw new XamlParserException("A 'x:Key' attribute is not allowed at the XAML root element");
            }
            foreach (EvaluatableMarkupExtensionActivator activator in _deferredMarkupExtensionActivations)
            {
                activator.Activate();
            }
            return(_rootObject);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Parses the contents of an <see cref="XmlNode"/> (not the node itself!).
        /// Parsed will be instances of <see cref="XmlAttribute"/> and <see cref="XmlElement"/>.
        /// In case the node is an <see cref="XmlAttribute"/>, its value will be parsed
        /// and returned. This will normally be a string or an instance of a
        /// markup extension. In case the node is an <see cref="XmlElement"/>,
        /// its children will be instantiatedan returned as an <see cref="IList"/> or
        /// an <see cref="IDictionary"/>, depending on whether the elements have a
        /// <c>x:Key</c> attribute associated.
        /// </summary>
        /// <param name="node">The XML node, an <see cref="XmlAttribute"/> or
        /// an <see cref="XmlElement"/>, whose contents should be parsed.</param>
        /// <returns>Parsed value. This is either a string, a markup extension
        /// instance, an <c>IList&lt;object&gt;</c> or an <c>IDictionary&lt;object, object&gt;</c>.</returns>
        protected object ParseValue(XmlNode node)
        {
            if (node is XmlAttribute) // Member attribute
            {
                return(ParseValue(node.Value));
            }
            if (!(node is XmlElement))
            {
                return(null);
            }

            // Handle explicit or implicit (Content) member element
            // Return value's type will be either a dict or a list, depending on contents
            IList <object> resultList = new List <object>();
            IDictionary <object, object> resultDict = new Dictionary <object, object>();

            foreach (XmlNode childNode in node.ChildNodes)
            {
                if (childNode is XmlElement)
                {
                    if (childNode.LocalName.IndexOf('.') != -1) // "." is used as indicator that we have a member declaration
                    // Ignore member assignments here - we focus on our real children
                    {
                        continue;
                    }
                    object key;
                    object value = Instantiate((XmlElement)childNode, out key);
                    if (key == null)
                    {
                        key = GetImplicitKey(value);
                    }
                    IEvaluableMarkupExtension evaluableMarkupExtension = value as IEvaluableMarkupExtension;
                    // Handle the case if a markup extension was instantiated as a child
                    if (evaluableMarkupExtension != null)
                    {
                        evaluableMarkupExtension.Initialize(this);
                        if (!evaluableMarkupExtension.Evaluate(out value))
                        {
                            throw new XamlParserException("Could not evaluate markup extension '{0}'", evaluableMarkupExtension);
                        }
                    }
                    value = ParserHelper.UnwrapIncludesAndCleanup(value);
                    if (key == null)
                    {
                        resultList.Add(value);
                    }
                    else
                    {
                        try
                        {
                            resultDict.Add(key, value);
                        }
                        catch (ArgumentException e)
                        {
                            throw new XamlParserException("Duplicate key '{0}'", e, key);
                        }
                    }
                    // If a key was provided, register the new element in the current context.
                    // This is necessary if the new element should be accessed before all children
                    // here created are added to their target collection.
                    if (key != null)
                    {
                        _elementContextStack.CurrentElementContext.AddKeyedElement(key, value);
                    }
                }
                else if (childNode is XmlText || childNode is XmlCDataSection) // Ignore other XmlCharacterData nodes
                {
                    resultList.Add(((XmlCharacterData)childNode).Data);
                }
            }
            if (resultList.Count > 0 && resultDict.Count > 0)
            {
                throw new XamlBindingException(
                          "Xaml parser parsing Element '{0}': Child elements containing x:Key attributes cannot be mixed with child elements without x:Key attribute",
                          node.Name);
            }

            if (resultDict.Count > 0)
            {
                return(resultDict);
            }
            return(resultList.Count == 0 ? null : (resultList.Count == 1 ? resultList[0] : resultList));
        }