示例#1
0
        /// <summary>
        /// Parses the next parameter in the specified <paramref name="expr"/>.
        /// The returned value will indicate the index in this string following
        /// the parameter declaration.
        /// </summary>
        /// <remarks>
        /// Parses in the specified <paramref name="expr"/> beginning at the specified
        /// <paramref name="index"/> a XAML markup extension parameter specification
        /// of the form
        /// <code>
        /// 1)
        /// [Name]=[Value]
        /// </code>
        /// or
        /// <code>
        /// 2)
        /// [Value]
        /// </code>
        /// The value itself may be a simple string value or an instantiation of
        /// another element, surrounded by { and } characters.
        /// If form 1 is found, the returned parameter
        /// <paramref name="name"/> will contain the parsed name part, if form 2 is
        /// found, the <paramref name="name"/> parameter will be null.
        /// In both forms the <paramref name="value"/> parameter will contain the
        /// parsed value string.
        /// </remarks>
        /// <returns>The index in the <paramref name="expr"/> string following
        /// the parameter declaration.</returns>
        private static int ParseParameter(string expr, int index, out string name, out string value)
        {
            index = ParserHelper.SkipSpaces(expr, index);
            if (index >= expr.Length)
            {
                throw new XamlParserException("Object instantiation expression '{0}': '=' expected at position {1}", expr, index);
            }

            string nameOrValue;

            index = ParseNameOrValue(expr, index, out nameOrValue);
            index = ParserHelper.SkipSpaces(expr, index);
            if (index < expr.Length && expr[index] == '=')
            {
                name   = nameOrValue;
                index += 1;
                index  = ParseNameOrValue(expr, index, out value);
                index  = ParserHelper.SkipSpaces(expr, index);
            }
            else
            {
                name  = null;
                value = nameOrValue;
            }
            return(index);
        }
示例#2
0
        /// <summary>
        /// Parses an expression in an attribute value syntax for instantiating an element
        /// like a markup extension. The specified expression string must not contain
        /// the starting { and ending } characters.
        /// </summary>
        /// <param name="expr">Expression representing an object instantiation.
        /// This expression has the syntax
        /// <code>
        /// Object-Instantiation := [Expression-Name] <[Property]=[Value]<, ...>>
        /// </code>
        /// or
        /// <code>
        /// Object-Instantiation := [Expression-Name] <[Value]<, ...>>
        /// </code>
        /// Every parameter itself can again be a simple value assignment or an
        /// instantiation of another element.
        /// In this case, the according value expression has the syntax
        /// <code>
        /// [Value]={[Object-Instantiation]}
        /// </code></param>
        /// <param name="extensionName">Will be assigned to the name of the element
        /// instantiate.</param>
        /// <param name="parameters">Will contain a list of parameter assignments.</param>
        /// <param name="namedParams">Will contain the information, if the parameters
        /// are given in a <c>name = value</c> syntax or in a <c>param</c> syntax.
        /// Mixed syntax forms for different parameters are not supported.
        /// If no parameters were found, <paramref name="namedParams"/> will be set
        /// to <c>false</c>.</param>
        public static void ParseInstantiationExpression(string expr,
                                                        out string extensionName, out IList <KeyValuePair <string, string> > parameters,
                                                        out bool namedParams)
        {
            parameters = new List <KeyValuePair <string, string> >();
            int i = expr.IndexOf(' ');

            if (i == -1)
            {
                extensionName = expr;
                namedParams   = false;
            }
            else
            {
                extensionName = expr.Substring(0, i);
                i             = ParserHelper.SkipSpaces(expr, i);
                bool?allNamedParams = null;
                while (i < expr.Length)
                {
                    string name;
                    string value;
                    i = ParseParameter(expr, i, out name, out value);
                    parameters.Add(new KeyValuePair <string, string>(name, value));
                    bool hasName = !string.IsNullOrEmpty(name);
                    if (allNamedParams == null)
                    {
                        allNamedParams = hasName;
                    }
                    else if (allNamedParams.Value != hasName)
                    {
                        throw new XamlParserException("Object instantiation expression '{0}', position {1}: mixed named and unnamed parameters are not allowed", expr, i);
                    }
                    i = ParserHelper.SkipSpaces(expr, i);
                    if (i >= expr.Length)
                    {
                        break; // End of expression reached - all parameters processed
                    }
                    if (expr[i] != ',')
                    {
                        throw new XamlParserException("Object instantiation expression syntax '{0}' is invalid at position {1}", expr, i);
                    }
                    i++;
                    i = ParserHelper.SkipSpaces(expr, i);
                    if (i >= expr.Length)
                    {
                        throw new XamlParserException("Object instantiation expression '{0}': parameter expected at position {1}", expr, i);
                    }
                }
                namedParams = (allNamedParams ?? false); // Default when no params were parsed: namedParams == false
            }
        }
示例#3
0
        protected static int ParsePathSegment(IParserContext context, string path, int pos, out IPathSegment result)
        {
            pos = ParserHelper.SkipSpaces(path, pos);
            if (path[pos] == '[')
            { // Indexer expression
                object[] indices;
                pos    = ParseIndices(context, path, pos, out indices);
                result = new IndexerPathSegment(indices);
                return(pos);
            }
            if (path[pos] == '(')
            { // Attached property
                int bracket = path.IndexOf(")", pos);
                if (bracket == -1)
                {
                    throw new XamlParserException("Path '{0}': ')' expected", path);
                }
                int dot = path.IndexOf('.', pos);
                if (dot == -1 || dot > bracket)
                {
                    throw new XamlParserException("Path '{0}': Attached property expected", path);
                }
                string propertyProvider = path.Substring(pos + 1, dot - pos - 1);
                string propertyName     = path.Substring(dot + 1, bracket - dot - 1);
                string namespaceURI;
                context.LookupNamespace(propertyProvider, out propertyProvider, out namespaceURI);
                result = new AttachedPropertyPathSegment(context, propertyProvider, propertyName, namespaceURI);
                return(bracket + 1);
            }
            // Member
            int end = path.IndexOfAny(new char[] { '.', '[' }, pos);

            if (end == -1)
            {
                end = path.Length;
            }
            result = new MemberPathSegment(path.Substring(pos, end - pos));

            if (path.IndexOf('[', pos) == end)
            { // Index follows member name
                object[] indices;
                end = ParseIndices(context, path, end, out indices);
                ((MemberPathSegment)result).SetIndices(indices);
            }
            return(end);
        }