private void PrepareIndexForIndexer(PropertyInfo indexer) { Type indexType = indexer.GetIndexParameters().First().ParameterType; try { this._parsedIndex = Convert.ChangeType(this._index, indexType); } catch (Exception) { if (TypeFromStringConverters.CanTypeBeConverted(indexType)) { this._parsedIndex = TypeFromStringConverters.ConvertFromInvariantString(indexType, this._index); //todo: maybe in try / catch ? } else { this._parsedIndex = this._index; //todo: maybe null ? } } }
private object EnsurePropertyType(object item, Type targetType) { if (targetType == null || item == null) { return(item); } Type itemType = item.GetType(); if (targetType.IsAssignableFrom(itemType)) { return(item); } else if (itemType == typeof(string) && TypeFromStringConverters.CanTypeBeConverted(targetType)) { return(TypeFromStringConverters.ConvertFromInvariantString(targetType, (string)item)); } else { //note: can crash return(Convert.ChangeType(item, targetType)); } }
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; } } }