public void Should_Build_Stream_Node()
        {
            var result = ToList(ExpressionObserverBuilder.Parse("Foo^"));

            Assert.Equal(2, result.Count);
            Assert.IsType <StreamNode>(result[1]);
        }
        public void Should_Build_Dot()
        {
            var result = ToList(ExpressionObserverBuilder.Parse("."));

            Assert.Equal(1, result.Count);
            Assert.IsType <EmptyExpressionNode>(result[0]);
        }
        public void Should_Build_Multiple_Indexed_Property_With_Space()
        {
            var result = ToList(ExpressionObserverBuilder.Parse("Foo[5, 16]"));

            Assert.Equal(2, result.Count);
            AssertIsProperty(result[0], "Foo");
            AssertIsIndexer(result[1], "5", "16");
        }
        public void Should_Build_Indexed_Property_StringIndex()
        {
            var result = ToList(ExpressionObserverBuilder.Parse("Foo[Key]"));

            Assert.Equal(2, result.Count);
            AssertIsProperty(result[0], "Foo");
            AssertIsIndexer(result[1], "Key");
            Assert.IsType <StringIndexerNode>(result[1]);
        }
        public void Should_Build_Consecutive_Indexers()
        {
            var result = ToList(ExpressionObserverBuilder.Parse("Foo[15][16]"));

            Assert.Equal(3, result.Count);
            AssertIsProperty(result[0], "Foo");
            AssertIsIndexer(result[1], "15");
            AssertIsIndexer(result[2], "16");
        }
        public void Should_Build_Property_Chain()
        {
            var result = ToList(ExpressionObserverBuilder.Parse("Foo.Bar.Baz"));

            Assert.Equal(3, result.Count);
            AssertIsProperty(result[0], "Foo");
            AssertIsProperty(result[1], "Bar");
            AssertIsProperty(result[2], "Baz");
        }
        public void Should_Build_Negated_Property_Chain()
        {
            var result = ToList(ExpressionObserverBuilder.Parse("!Foo.Bar.Baz"));

            Assert.Equal(4, result.Count);
            Assert.IsType <LogicalNotNode>(result[0]);
            AssertIsProperty(result[1], "Foo");
            AssertIsProperty(result[2], "Bar");
            AssertIsProperty(result[3], "Baz");
        }
        public void Should_Build_Indexed_Property_In_Chain()
        {
            var result = ToList(ExpressionObserverBuilder.Parse("Foo.Bar[5, 6].Baz"));

            Assert.Equal(4, result.Count);
            AssertIsProperty(result[0], "Foo");
            AssertIsProperty(result[1], "Bar");
            AssertIsIndexer(result[2], "5", "6");
            AssertIsProperty(result[3], "Baz");
        }
Exemple #9
0
        protected override ExpressionObserver CreateExpressionObserver(IAvaloniaObject target, AvaloniaProperty targetProperty, object?anchor, bool enableDataValidation)
        {
            _ = target ?? throw new ArgumentNullException(nameof(target));

            anchor ??= DefaultAnchor?.Target;
            enableDataValidation = enableDataValidation && Priority == BindingPriority.LocalValue;

            INameScope?nameScope = null;

            NameScope?.TryGetTarget(out nameScope);

            var(node, mode) = ExpressionObserverBuilder.Parse(Path, enableDataValidation, TypeResolver, nameScope);

            if (node is null)
            {
                throw new InvalidOperationException("Could not parse binding expression.");
            }

            IStyledElement GetSource()
            {
                return(target as IStyledElement ??
                       anchor as IStyledElement ??
                       throw new ArgumentException("Could not find binding source: either target or anchor must be an IStyledElement."));
            }

            if (ElementName != null)
            {
                return(CreateElementObserver(
                           GetSource(),
                           ElementName,
                           node));
            }
            else if (Source != null)
            {
                return(CreateSourceObserver(Source, node));
            }
            else if (RelativeSource == null)
            {
                if (mode == SourceMode.Data)
                {
                    return(CreateDataContextObserver(
                               target,
                               node,
                               targetProperty == StyledElement.DataContextProperty,
                               anchor));
                }
                else
                {
                    return(CreateSourceObserver(GetSource(), node));
                }
            }
            else if (RelativeSource.Mode == RelativeSourceMode.DataContext)
            {
                return(CreateDataContextObserver(
                           target,
                           node,
                           targetProperty == StyledElement.DataContextProperty,
                           anchor));
            }
            else if (RelativeSource.Mode == RelativeSourceMode.Self)
            {
                return(CreateSourceObserver(GetSource(), node));
            }
            else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent)
            {
                return(CreateTemplatedParentObserver(GetSource(), node));
            }
            else if (RelativeSource.Mode == RelativeSourceMode.FindAncestor)
            {
                if (RelativeSource.Tree == TreeType.Visual && RelativeSource.AncestorType == null)
                {
                    throw new InvalidOperationException("AncestorType must be set for RelativeSourceMode.FindAncestor when searching the visual tree.");
                }

                return(CreateFindAncestorObserver(GetSource(), RelativeSource, node));
            }
            else
            {
                throw new NotSupportedException();
            }
        }
        public void Should_Build_Property_With_Digits()
        {
            var result = ToList(ExpressionObserverBuilder.Parse("F0o"));

            AssertIsProperty(result[0], "F0o");
        }
        public void Should_Build_Underscored_Property()
        {
            var result = ToList(ExpressionObserverBuilder.Parse("_Foo"));

            AssertIsProperty(result[0], "_Foo");
        }
        public void Should_Build_Single_Property()
        {
            var result = ToList(ExpressionObserverBuilder.Parse("Foo"));

            AssertIsProperty(result[0], "Foo");
        }
Exemple #13
0
        /// <inheritdoc/>
        public InstancedBinding Initiate(
            IAvaloniaObject target,
            AvaloniaProperty targetProperty,
            object anchor             = null,
            bool enableDataValidation = false)
        {
            Contract.Requires <ArgumentNullException>(target != null);
            anchor = anchor ?? DefaultAnchor?.Target;

            enableDataValidation = enableDataValidation && Priority == BindingPriority.LocalValue;

            ExpressionObserver observer;

            var(node, mode) = ExpressionObserverBuilder.Parse(Path, enableDataValidation, TypeResolver);

            if (ElementName != null)
            {
                observer = CreateElementObserver(
                    (target as IStyledElement) ?? (anchor as IStyledElement),
                    ElementName,
                    node);
            }
            else if (Source != null)
            {
                observer = CreateSourceObserver(Source, node);
            }
            else if (RelativeSource == null)
            {
                if (mode == SourceMode.Data)
                {
                    observer = CreateDataContextObserver(
                        target,
                        node,
                        targetProperty == StyledElement.DataContextProperty,
                        anchor);
                }
                else
                {
                    observer = new ExpressionObserver(
                        (target as IStyledElement) ?? (anchor as IStyledElement),
                        node);
                }
            }
            else if (RelativeSource.Mode == RelativeSourceMode.DataContext)
            {
                observer = CreateDataContextObserver(
                    target,
                    node,
                    targetProperty == StyledElement.DataContextProperty,
                    anchor);
            }
            else if (RelativeSource.Mode == RelativeSourceMode.Self)
            {
                observer = CreateSourceObserver(
                    (target as IStyledElement) ?? (anchor as IStyledElement),
                    node);
            }
            else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent)
            {
                observer = CreateTemplatedParentObserver(
                    (target as IStyledElement) ?? (anchor as IStyledElement),
                    node);
            }
            else if (RelativeSource.Mode == RelativeSourceMode.FindAncestor)
            {
                if (RelativeSource.Tree == TreeType.Visual && RelativeSource.AncestorType == null)
                {
                    throw new InvalidOperationException("AncestorType must be set for RelativeSourceMode.FindAncestor when searching the visual tree.");
                }

                observer = CreateFindAncestorObserver(
                    (target as IStyledElement) ?? (anchor as IStyledElement),
                    RelativeSource,
                    node);
            }
            else
            {
                throw new NotSupportedException();
            }

            var fallback = FallbackValue;

            // If we're binding to DataContext and our fallback is UnsetValue then override
            // the fallback value to null, as broken bindings to DataContext must reset the
            // DataContext in order to not propagate incorrect DataContexts to child controls.
            // See Avalonia.Markup.UnitTests.Data.DataContext_Binding_Should_Produce_Correct_Results.
            if (targetProperty == StyledElement.DataContextProperty && fallback == AvaloniaProperty.UnsetValue)
            {
                fallback = null;
            }

            var converter  = Converter;
            var targetType = targetProperty?.PropertyType ?? typeof(object);

            // We only respect `StringFormat` if the type of the property we're assigning to will
            // accept a string. Note that this is slightly different to WPF in that WPF only applies
            // `StringFormat` for target type `string` (not `object`).
            if (!string.IsNullOrWhiteSpace(StringFormat) &&
                (targetType == typeof(string) || targetType == typeof(object)))
            {
                converter = new StringFormatValueConverter(StringFormat, converter);
            }

            var subject = new BindingExpression(
                observer,
                targetType,
                fallback,
                converter ?? DefaultValueConverter.Instance,
                ConverterParameter,
                Priority);

            return(new InstancedBinding(subject, Mode, Priority));
        }
 public void Identifier_Cannot_Start_With_Symbol()
 {
     Assert.Throws <ExpressionParseException>(
         () => ExpressionObserverBuilder.Parse("Foo.%Bar"));
 }
Exemple #15
0
 public void Expression_Cannot_Start_With_Period_Then_Token()
 {
     Assert.Throws <ExpressionParseException>(
         () => ExpressionObserverBuilder.Parse(".Bar"));
 }
 public void Expression_Cannot_Have_Letter_After_Indexer()
 {
     Assert.Throws <ExpressionParseException>(
         () => ExpressionObserverBuilder.Parse("Foo.Bar[3,4]A"));
 }
 public void Expression_Cannot_Have_Extra_Comma_At_End_Of_Indexer()
 {
     Assert.Throws <ExpressionParseException>(
         () => ExpressionObserverBuilder.Parse("Foo.Bar[3,4,]"));
 }
 public void Expression_Cannot_Have_Empty_Indexer()
 {
     Assert.Throws <ExpressionParseException>(
         () => ExpressionObserverBuilder.Parse("Foo.Bar[]"));
 }
 public void Expression_Cannot_End_With_Period()
 {
     Assert.Throws <ExpressionParseException>(
         () => ExpressionObserverBuilder.Parse("Foo.Bar."));
 }
Exemple #20
0
        protected override ExpressionObserver CreateExpressionObserver(IAvaloniaObject target, AvaloniaProperty targetProperty, object anchor, bool enableDataValidation)
        {
            Contract.Requires <ArgumentNullException>(target != null);
            anchor = anchor ?? DefaultAnchor?.Target;

            enableDataValidation = enableDataValidation && Priority == BindingPriority.LocalValue;

            INameScope nameScope = null;

            NameScope?.TryGetTarget(out nameScope);

            var(node, mode) = ExpressionObserverBuilder.Parse(Path, enableDataValidation, TypeResolver, nameScope);

            if (ElementName != null)
            {
                return(CreateElementObserver(
                           (target as IStyledElement) ?? (anchor as IStyledElement),
                           ElementName,
                           node));
            }
            else if (Source != null)
            {
                return(CreateSourceObserver(Source, node));
            }
            else if (RelativeSource == null)
            {
                if (mode == SourceMode.Data)
                {
                    return(CreateDataContextObserver(
                               target,
                               node,
                               targetProperty == StyledElement.DataContextProperty,
                               anchor));
                }
                else
                {
                    return(CreateSourceObserver(
                               (target as IStyledElement) ?? (anchor as IStyledElement),
                               node));
                }
            }
            else if (RelativeSource.Mode == RelativeSourceMode.DataContext)
            {
                return(CreateDataContextObserver(
                           target,
                           node,
                           targetProperty == StyledElement.DataContextProperty,
                           anchor));
            }
            else if (RelativeSource.Mode == RelativeSourceMode.Self)
            {
                return(CreateSourceObserver(
                           (target as IStyledElement) ?? (anchor as IStyledElement),
                           node));
            }
            else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent)
            {
                return(CreateTemplatedParentObserver(
                           (target as IStyledElement) ?? (anchor as IStyledElement),
                           node));
            }
            else if (RelativeSource.Mode == RelativeSourceMode.FindAncestor)
            {
                if (RelativeSource.Tree == TreeType.Visual && RelativeSource.AncestorType == null)
                {
                    throw new InvalidOperationException("AncestorType must be set for RelativeSourceMode.FindAncestor when searching the visual tree.");
                }

                return(CreateFindAncestorObserver(
                           (target as IStyledElement) ?? (anchor as IStyledElement),
                           RelativeSource,
                           node));
            }
            else
            {
                throw new NotSupportedException();
            }
        }
 public void Identifier_Cannot_Start_With_Digit()
 {
     Assert.Throws <ExpressionParseException>(
         () => ExpressionObserverBuilder.Parse("1Foo"));
 }