示例#1
0
        /// <summary>
        /// Parses a <see cref="Selector"/> from a string.
        /// </summary>
        /// <param name="s">The string.</param>
        /// <returns>The parsed selector.</returns>
        public Selector Parse(string s)
        {
            var syntax = SelectorGrammar.Selector.Parse(s);
            var result = new Selector();

            foreach (var i in syntax)
            {
                var ofType = i as SelectorGrammar.OfTypeSyntax;
                var @is = i as SelectorGrammar.IsSyntax;
                var @class = i as SelectorGrammar.ClassSyntax;
                var name = i as SelectorGrammar.NameSyntax;
                var property = i as SelectorGrammar.PropertySyntax;
                var child = i as SelectorGrammar.ChildSyntax;
                var descendent = i as SelectorGrammar.DescendentSyntax;
                var template = i as SelectorGrammar.TemplateSyntax;

                if (ofType != null)
                {
                    result = result.OfType(_typeResolver(ofType.TypeName, ofType.Xmlns));
                }
                if (@is != null)
                {
                    result = result.Is(_typeResolver(@is.TypeName, @is.Xmlns));
                }
                else if (@class != null)
                {
                    result = result.Class(@class.Class);
                }
                else if (name != null)
                {
                    result = result.Name(name.Name);
                }
                else if (property != null)
                {
                    var type = result.TargetType;

                    if (type == null)
                    {
                        throw new InvalidOperationException("Property selectors must be applied to a type.");
                    }

                    var targetProperty = PerspexPropertyRegistry.Instance.FindRegistered(type, property.Property);

                    if (targetProperty == null)
                    {
                        throw new InvalidOperationException($"Cannot find '{property.Property}' on '{type}");
                    }

                    object typedValue;

                    if (TypeUtilities.TryConvert(
                            targetProperty.PropertyType, 
                            property.Value, 
                            CultureInfo.InvariantCulture,
                            out typedValue))
                    {
                        result = result.PropertyEquals(targetProperty, typedValue);
                    }
                    else
                    {
                        throw new InvalidOperationException(
                            $"Could not convert '{property.Value}' to '{targetProperty.PropertyType}");
                    }
                }
                else if (child != null)
                {
                    result = result.Child();
                }
                else if (descendent != null)
                {
                    result = result.Descendent();
                }
                else if (template != null)
                {
                    result = result.Template();
                }
            }

            return result;
        }