Пример #1
0
        internal PropertyPathWalker(string path, bool isDatacontextBound)
        {
            _path = path;
            _isDataContextBound = isDatacontextBound;

            if (_isDataContextBound)
            {
                _firstNode = new DependencyPropertyNode(FrameworkElement.DataContextProperty);
            }

            ParsePath(_path, out IPropertyPathNode head, out IPropertyPathNode tail);

            if (_firstNode == null)
            {
                _firstNode = head ?? new StandardPropertyPathNode();
            }
            else
            {
                _firstNode.Next = head;
            }

            FinalNode = tail ?? _firstNode;

            FinalNode.Listen(this);
        }
Пример #2
0
        void IPropertyPathNodeListener.ValueChanged(IPropertyPathNode node)
        {
            ValueInternal = node.Value;
            IPropertyPathWalkerListener listener = _listener;

            if (listener != null)
            {
                listener.ValueChanged();
            }
        }
Пример #3
0
        void IPropertyPathNodeListener.IsBrokenChanged(IPropertyPathNode node)
        {
            ValueInternal = node.Value;
            var listener = _listener;

            if (listener != null)
            {
                listener.IsBrokenChanged();
            }
        }
        private void OnSourcePropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if ((e.PropertyName == _propertyName || string.IsNullOrEmpty(e.PropertyName)) && (_prop != null || _field != null))
            {
                UpdateValue();

                IPropertyPathNode next = Next;
                if (next != null)
                {
                    next.SetSource(Value);
                }
            }
        }
Пример #5
0
        private void ParsePath(string path, out IPropertyPathNode head, out IPropertyPathNode tail)
        {
            head = null;
            tail = null;

            var parser = new PropertyPathParser(path);
            PropertyNodeType type;

            while ((type = parser.Step(out string typeName, out string propertyName, out string index)) != PropertyNodeType.None)
            {
                IPropertyPathNode node;
                switch (type)
                {
                case PropertyNodeType.AttachedProperty:
                case PropertyNodeType.Property:
                    node = new StandardPropertyPathNode(typeName, propertyName);
                    break;

                case PropertyNodeType.Indexed:
                    node = new IndexedPropertyPathNode(index);
                    break;

                default:
                    throw new InvalidOperationException();
                }

                if (head == null)
                {
                    head = tail = node;
                    continue;
                }

                tail.Next = node;
                tail      = node;
            }
        }
Пример #6
0
        /// <summary>
        /// This method is used to check whether the value is Valid if needed.
        /// </summary>
        /// <param name="initialValue"></param>
        internal void CheckInitialValueValidity(object initialValue)
        {
            if (ParentBinding.ValidatesOnExceptions && ParentBinding.ValidatesOnLoad)
            {
                if (!_propertyPathWalker.IsPathBroken)
                {
                    INTERNAL_ForceValidateOnNextSetValue = false;
                    try
                    {
                        IPropertyPathNode node = _propertyPathWalker.FinalNode;
                        node.SetValue(node.Value); //we set the source property to its own value to check whether it causes an exception, in which case the value is not valid.
                    }
                    catch (Exception e)            //todo: put the content of this catch in a method which will be called here and in UpdateSourceObject (OR put the whole try/catch in the method and put the Value to set as parameter).
                    {
                        //We get the new Error (which is the innermost exception as far as I know):
                        Exception currentException = e;
#if OPENSILVER
                        if (true)                                    // Note: "InnerException" is only supported in the Simulator as of July 27, 2017.
#elif BRIDGE
                        if (CSHTML5.Interop.IsRunningInTheSimulator) // Note: "InnerException" is only supported in the Simulator as of July 27, 2017.
#endif
                        {
                            while (currentException.InnerException != null)
                            {
                                currentException = currentException.InnerException;
                            }
                        }

                        Validation.MarkInvalid(this, new ValidationError(this)
                        {
                            Exception = currentException, ErrorContent = currentException.Message
                        });
                    }
                }
            }
        }
Пример #7
0
        internal PropertyPathWalker(string path, bool isDatacontextBound)
        {
            Path = path;
            StandardPropertyPathNode lastNode;

            IsDataContextBound = isDatacontextBound;

            if (path == null || path == ".")
            {
                //bindsDirectlyToSource set to true means that the binding is directly made to the source (--> there is no path)
                lastNode  = new StandardPropertyPathNode(); //what to put in there ?
                FirstNode = lastNode;
                FinalNode = lastNode;
            }
            else
            {
                PropertyNodeType type;
                var    parser = new PropertyPathParser(path);
                string typeName;
                string propertyName;
                int    index;
                //IPropertyPathNode node;
                while ((type = parser.Step(out typeName, out propertyName, out index)) != PropertyNodeType.None)
                {
                    //we make node advance (when it is not the first step, otherwise it stays at null)
                    //node = FinalNode;

                    //var isViewProperty = false;
                    //boolean isViewProperty = CollectionViewProperties.Any (prop => prop.Name == propertyName);
                    //          static readonly PropertyInfo[] CollectionViewProperties = typeof (ICollectionView).GetProperties ();

                    switch (type)
                    {
                    case PropertyNodeType.AttachedProperty:
                    case PropertyNodeType.Property:
                        if (FinalNode == null)
                        {
                            FinalNode = new StandardPropertyPathNode(typeName, propertyName);
                        }
                        else
                        {
                            FinalNode.Next = new StandardPropertyPathNode(typeName, propertyName);
                        }
                        break;

                    case PropertyNodeType.Indexed:
                        throw new NotImplementedException("Indexed properties are not supported yet.");
                        //todo: when we will handle the indexed properties, uncomment the following
                        //node.Next = new IndexedPropertyPathNode(index);
                        break;

                    default:
                        break;
                    }

                    if (FirstNode == null)
                    {
                        FirstNode = FinalNode;
                    }

                    if (FinalNode.Next != null)
                    {
                        FinalNode = FinalNode.Next;
                    }
                }
            }

            this.FinalNode.Listen(this);
        }
Пример #8
0
        internal void UpdateSourceObject(object value)
        {
            if (_propertyPathWalker.IsPathBroken)
            {
                return;
            }

            IPropertyPathNode node = _propertyPathWalker.FinalNode;
            bool oldIsUpdating     = IsUpdating;

            object convertedValue = value;
            Type   expectedType   = node.Type;

            try
            {
                if (expectedType != null && ParentBinding.Converter != null)
                {
#if MIGRATION
                    convertedValue = ParentBinding.Converter.ConvertBack(value, expectedType, ParentBinding.ConverterParameter, ParentBinding.ConverterCulture);
#else
                    convertedValue = ParentBinding.Converter.ConvertBack(value, expectedType, ParentBinding.ConverterParameter, ParentBinding.ConverterLanguage);
#endif

                    if (convertedValue == DependencyProperty.UnsetValue)
                    {
                        return;
                    }
                }

                if (!IsValueValidForSourceUpdate(convertedValue, expectedType))
                {
                    IsUpdating = true;

#if MIGRATION
                    convertedValue = DynamicConverter.Convert(convertedValue, expectedType, null, ParentBinding.ConverterCulture);
#else
                    convertedValue = DynamicConverter.Convert(convertedValue, expectedType, null, ParentBinding.ConverterLanguage);
#endif

                    if (convertedValue == DependencyProperty.UnsetValue)
                    {
                        return;
                    }
                }

                node.SetValue(convertedValue);
                Validation.ClearInvalid(this);
            }
            catch (Exception e)
            {
                //If we have ValidatesOnExceptions set to true, we display a popup with the error close to the element.
                if (ParentBinding.ValidatesOnExceptions)
                {
                    //We get the new Error (which is the innermost exception as far as I know):
                    Exception currentException = e;

                    while (currentException.InnerException != null)
                    {
                        currentException = currentException.InnerException;
                    }

                    Validation.MarkInvalid(this, new ValidationError(this)
                    {
                        Exception = currentException, ErrorContent = currentException.Message
                    });
                }
            }
            finally
            {
                IsUpdating = oldIsUpdating;
            }
        }