Пример #1
0
        public ExpressionNode BuildExpression(bool enableValidation)
        {
            ExpressionNode pathRoot = null;
            ExpressionNode path     = null;

            foreach (var element in _elements)
            {
                ExpressionNode node = null;
                switch (element)
                {
                case NotExpressionPathElement _:
                    node = new LogicalNotNode();
                    break;

                case PropertyElement prop:
                    node = new PropertyAccessorNode(prop.Property.Name, enableValidation, new PropertyInfoAccessorPlugin(prop.Property, prop.AccessorFactory));
                    break;

                case ArrayElementPathElement arr:
                    node = new PropertyAccessorNode(CommonPropertyNames.IndexerName, enableValidation, new ArrayElementPlugin(arr.Indices, arr.ElementType));
                    break;

                case VisualAncestorPathElement visualAncestor:
                    node = new FindVisualAncestorNode(visualAncestor.AncestorType, visualAncestor.Level);
                    break;

                case AncestorPathElement ancestor:
                    node = new FindAncestorNode(ancestor.AncestorType, ancestor.Level);
                    break;

                case SelfPathElement _:
                    node = new SelfNode();
                    break;

                case ElementNameElement name:
                    node = new ElementNameNode(name.NameScope, name.Name);
                    break;

                case IStronglyTypedStreamElement stream:
                    node = new StreamNode(stream.CreatePlugin());
                    break;

                case ITypeCastElement typeCast:
                    node = new StrongTypeCastNode(typeCast.Type, typeCast.Cast);
                    break;

                default:
                    throw new InvalidOperationException($"Unknown binding path element type {element.GetType().FullName}");
                }

                path = pathRoot is null ? (pathRoot = node) : path.Next = node;
            }

            return(pathRoot ?? new EmptyExpressionNode());
        }
Пример #2
0
        public void Should_Not_Throw_Exception_On_Duplicate_Properties()
        {
            // Repro of https://github.com/AvaloniaUI/Avalonia/issues/4733.
            var source = new MyViewModel();
            var target = new PropertyAccessorNode("Name", false);

            target.Target = new WeakReference <object>(source);

            var result = new List <object>();

            target.Subscribe(x => result.Add(x));
        }
        public void Should_Not_Throw_Exception_On_Unsubscribe_When_Already_Unsubscribed()
        {
            var source = new Class1 {
                Foo = "foo"
            };
            var target = new PropertyAccessorNode("Foo", false);

            Assert.NotNull(target);
            target.Target = new WeakReference <object>(source);
            target.Subscribe(_ => { });
            target.Unsubscribe();
            target.Unsubscribe();
            Assert.True(true);
        }
Пример #4
0
        public void Should_Not_Throw_Exception_When_Enabling_Data_Validation_On_Missing_Member()
        {
            var source = new Class1();
            var target = new PropertyAccessorNode("NotFound", true);

            target.Target = new WeakReference <object>(source);

            var result = new List <object>();

            target.Subscribe(x => result.Add(x));

            Assert.Equal(
                new object[]
            {
                new BindingNotification(
                    new MissingMemberException("Could not find a matching property accessor for 'NotFound' on 'Avalonia.Base.UnitTests.Data.Core.ExpressionObserverTests_Property+Class1'"),
                    BindingErrorType.Error),
            },
                result);
        }
Пример #5
0
        public (ExpressionNode?Node, SourceMode Mode) Parse(ref CharacterReader r)
        {
            ExpressionNode?rootNode = null;
            ExpressionNode?node     = null;

            var(astNodes, mode) = BindingExpressionGrammar.Parse(ref r);

            foreach (var astNode in astNodes)
            {
                ExpressionNode?nextNode = null;
                switch (astNode)
                {
                case BindingExpressionGrammar.EmptyExpressionNode _:
                    nextNode = new EmptyExpressionNode();
                    break;

                case BindingExpressionGrammar.NotNode _:
                    nextNode = new LogicalNotNode();
                    break;

                case BindingExpressionGrammar.StreamNode _:
                    nextNode = new StreamNode();
                    break;

                case BindingExpressionGrammar.PropertyNameNode propName:
                    nextNode = new PropertyAccessorNode(propName.PropertyName, _enableValidation);
                    break;

                case BindingExpressionGrammar.IndexerNode indexer:
                    nextNode = new StringIndexerNode(indexer.Arguments);
                    break;

                case BindingExpressionGrammar.AttachedPropertyNameNode attachedProp:
                    nextNode = ParseAttachedProperty(attachedProp);
                    break;

                case BindingExpressionGrammar.SelfNode _:
                    nextNode = new SelfNode();
                    break;

                case BindingExpressionGrammar.AncestorNode ancestor:
                    nextNode = ParseFindAncestor(ancestor);
                    break;

                case BindingExpressionGrammar.NameNode elementName:
                    nextNode = new ElementNameNode(_nameScope ?? throw new NotSupportedException("Invalid element name binding with null name scope!"), elementName.Name);
                    break;

                case BindingExpressionGrammar.TypeCastNode typeCast:
                    nextNode = ParseTypeCastNode(typeCast);
                    break;
                }
                if (node is null)
                {
                    rootNode = node = nextNode;
                }
                else
                {
                    node.Next = nextNode;
                    node      = nextNode;
                }
            }

            return(rootNode, mode);
        }