Esempio n. 1
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
                    {
                        PropertyPathNode node = (PropertyPathNode)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 (Interop.IsRunningInTheSimulator) // Note: "InnerException" is only supported in the Simulator as of July 27, 2017.
                        {
                            while (currentException.InnerException != null)
                            {
                                currentException = currentException.InnerException;
                            }
                        }

                        Validation.MarkInvalid(this, new ValidationError(this)
                        {
                            Exception = currentException, ErrorContent = currentException.Message
                        });
                    }
                }
            }
        }
        public static PropertyObservable <TProperty> CreateFromPropertySelector <TSubject, TProperty>(TSubject subject, Expression <Func <TSubject, TProperty> > propertySelector)
            where TSubject : INotifyPropertyChanged
        {
            if (!(propertySelector.Body is MemberExpression current))
            {
                throw new ArgumentException();
            }

            var result = new PropertyObservable <TProperty>();

            result.SetRootNode(PropertyPathNode.CreateFromPropertySelector(propertySelector));
            result.SetSource(subject);
            return(result);
        }
Esempio n. 3
0
        internal void UpdateSourceObject(object value)
        {
            if (!PropertyPathWalker.IsPathBroken)
            {
                PropertyPathNode node          = (PropertyPathNode)PropertyPathWalker.FinalNode;
                bool             oldIsUpdating = IsUpdating;

                try
                {
                    Type   expectedType   = null;
                    object convertedValue = value;
                    if (ParentBinding.Converter != null)
                    {
                        if (node.DependencyProperty != null)
                        {
#if MIGRATION
                            convertedValue = ParentBinding.Converter.ConvertBack(value, node.DependencyProperty.PropertyType, ParentBinding.ConverterParameter, ParentBinding.ConverterCulture);
#else
                            convertedValue = ParentBinding.Converter.ConvertBack(value, node.DependencyProperty.PropertyType, ParentBinding.ConverterParameter, ParentBinding.ConverterLanguage);
#endif
                            expectedType = node.DependencyProperty.PropertyType;
                        }
                        else if (node.PropertyInfo != null)
                        {
#if MIGRATION
                            convertedValue = ParentBinding.Converter.ConvertBack(value, node.PropertyInfo.PropertyType, ParentBinding.ConverterParameter, ParentBinding.ConverterCulture);
#else
                            convertedValue = ParentBinding.Converter.ConvertBack(value, node.PropertyInfo.PropertyType, ParentBinding.ConverterParameter, ParentBinding.ConverterLanguage);
#endif
                            expectedType = node.PropertyInfo.PropertyType;
                        }
                        else if (node.FieldInfo != null)
                        {
#if MIGRATION
                            convertedValue = ParentBinding.Converter.ConvertBack(value, node.FieldInfo.FieldType, ParentBinding.ConverterParameter, ParentBinding.ConverterCulture);
#else
                            convertedValue = ParentBinding.Converter.ConvertBack(value, node.FieldInfo.FieldType, ParentBinding.ConverterParameter, ParentBinding.ConverterLanguage);
#endif
                            expectedType = node.FieldInfo.FieldType;
                        }
                    }
                    else //we only need to set expectedType:
                    {
                        if (node.DependencyProperty != null)
                        {
                            expectedType = node.DependencyProperty.PropertyType;
                        }
                        else if (node.PropertyInfo != null)
                        {
                            expectedType = node.PropertyInfo.PropertyType;
                        }
                        else if (node.FieldInfo != null)
                        {
                            expectedType = node.FieldInfo.FieldType;
                        }
                    }

                    bool typeAcceptsNullAsValue    = !expectedType.IsValueType || expectedType.FullName.StartsWith("System.Nullable`1");
                    bool isNotNullOrIsNullAccepted = ((convertedValue != null) || typeAcceptsNullAsValue);
                    if (isNotNullOrIsNullAccepted) //Note: we put this test here to avoid making unneccessary tests but the point is that the new value is simply ignored since it doesn't fit the property (cannot set a non-nullable property to null).
                    {
                        //bool oldIsUpdating = IsUpdating;
                        IsUpdating = true;
                        Type[] AutoConvertTypes = { typeof(Int16), typeof(Int32), typeof(Int64), typeof(Double), typeof(Uri) };
                        bool   typeFound        = false;
                        if ((AutoConvertTypes.Contains(expectedType)) &&
                            convertedValue is string)    //todo: find a way to do this more efficiently (and maybe mode generic ?)
                        {
                            typeFound = true;
                            if (expectedType == typeof(Int16))
                            {
                                convertedValue = Int16.Parse((string)convertedValue);
                            }
                            else if (expectedType == typeof(Int32))
                            {
                                convertedValue = Int32.Parse((string)convertedValue);
                            }
                            else if (expectedType == typeof(Int64))
                            {
                                convertedValue = Int64.Parse((string)convertedValue);
                            }
                            else if (expectedType == typeof(Double))
                            {
                                convertedValue = Double.Parse((string)convertedValue);
                            }
                            else if (expectedType == typeof(Uri))
                            {
                                convertedValue = new Uri((string)convertedValue);
                            }
                        }

                        //todo: partially merge this "if" and the previous one.
                        if ((!typeFound && TypeFromStringConverters.CanTypeBeConverted(expectedType)) &&
                            convertedValue is string)
                        {
                            typeFound      = true;
                            convertedValue = TypeFromStringConverters.ConvertFromInvariantString(expectedType, (string)convertedValue);
                        }

                        if (!typeFound && convertedValue != null && (expectedType == typeof(string)))
                        {
                            convertedValue = convertedValue.ToString();
                        }

                        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;

                        if (Interop.IsRunningInTheSimulator) // Note: "InnerException" is only supported in the Simulator as of July 27, 2017.
                        {
                            while (currentException.InnerException != null)
                            {
                                currentException = currentException.InnerException;
                            }
                        }

                        Validation.MarkInvalid(this, new ValidationError(this)
                        {
                            Exception = currentException, ErrorContent = currentException.Message
                        });
                    }
                }
                finally
                {
                    IsUpdating = oldIsUpdating;
                }
            }
        }
 internal void SetRootNode(PropertyPathNode rootNode)
 {
     RootNode?.SetCallback(null);
     rootNode?.SetCallback(RaisePropertyChanged);
     RootNode = rootNode;
 }