private static object TryAddition(object currentValue, object value) { object returnValue = null; Type valueType = value.GetType(); Type additiveType = currentValue.GetType(); MethodInfo uniqueAdditionOperation = null; object convertedValue = value; foreach (MethodInfo additionOperation in additiveType.GetMethods()) { if (string.Compare(additionOperation.Name, "op_Addition", StringComparison.Ordinal) != 0) { continue; } ParameterInfo[] parameters = additionOperation.GetParameters(); Debug.Assert(parameters.Length == 2, "op_Addition is expected to have 2 parameters"); Type secondParameterType = parameters[1].ParameterType; if (!parameters[0].ParameterType.IsAssignableFrom(additiveType)) { continue; } else if (!secondParameterType.IsAssignableFrom(valueType)) { TypeConverter additionConverter = TypeConverterHelper.GetTypeConverter(secondParameterType); if (additionConverter.CanConvertFrom(valueType)) { convertedValue = TypeConverterHelper.DoConversionFrom(additionConverter, value); } else { continue; } } if (uniqueAdditionOperation != null) { throw new ArgumentException(string.Format( CultureInfo.CurrentCulture, ExceptionStringTable.ChangePropertyActionAmbiguousAdditionOperationExceptionMessage, additiveType.Name)); } uniqueAdditionOperation = additionOperation; } if (uniqueAdditionOperation != null) { returnValue = uniqueAdditionOperation.Invoke(null, new object[] { currentValue, convertedValue }); } else { // we couldn't figure out how to add, so pack it up and just set value returnValue = value; } return(returnValue); }
private object IncrementCurrentValue(PropertyInfo propertyInfo) { if (!propertyInfo.CanRead) { throw new InvalidOperationException(string.Format( CultureInfo.CurrentCulture, ExceptionStringTable.ChangePropertyActionCannotIncrementWriteOnlyPropertyExceptionMessage, propertyInfo.Name)); } object currentValue = propertyInfo.GetValue(this.Target, null); object returnValue = currentValue; Type propertyType = propertyInfo.PropertyType; TypeConverter converter = TypeConverterHelper.GetTypeConverter(propertyInfo.PropertyType); object value = this.Value; if (value == null || currentValue == null) { // we can't increment by null, so we'll attempt to set it instead // likewise, we can't increment, null by x, so we'll just set value instead return(value); } if (converter.CanConvertFrom(value.GetType())) { value = TypeConverterHelper.DoConversionFrom(converter, value); } if (typeof(double).IsAssignableFrom(propertyType)) { returnValue = (double)currentValue + (double)value; } else if (typeof(int).IsAssignableFrom(propertyType)) { returnValue = (int)currentValue + (int)value; } else if (typeof(float).IsAssignableFrom(propertyType)) { returnValue = (float)currentValue + (float)value; } else if (typeof(string).IsAssignableFrom(propertyType)) { returnValue = (string)currentValue + (string)value; } else { returnValue = TryAddition(currentValue, value); } return(returnValue); }
protected override void Invoke(object parameter) { if (this.AssociatedObject == null) { return; } if (string.IsNullOrEmpty(this.PropertyName)) { return; } if (this.Target == null) { return; } Type targetType = this.Target.GetType(); PropertyInfo propertyInfo = targetType.GetProperty(this.PropertyName); this.ValidateProperty(propertyInfo); object newValue = this.Value; TypeConverter converter = TypeConverterHelper.GetTypeConverter(propertyInfo.PropertyType); Exception innerException = null; try { if (this.Value != null) { if (converter != null && converter.CanConvertFrom(this.Value.GetType())) { newValue = converter.ConvertFrom(context: null, culture: CultureInfo.InvariantCulture, value: this.Value); } else { // Try asking the value if it can convert itself to the target property converter = TypeConverterHelper.GetTypeConverter(this.Value.GetType()); if (converter != null && converter.CanConvertTo(propertyInfo.PropertyType)) { newValue = converter.ConvertTo( context: null, culture: CultureInfo.InvariantCulture, value: this.Value, destinationType: propertyInfo.PropertyType); } } } // If a duration is set, we should animate this value. if (this.Duration.HasTimeSpan) { this.ValidateAnimationPossible(targetType); object fromValue = ChangePropertyAction.GetCurrentPropertyValue(this.Target, propertyInfo); this.AnimatePropertyChange(propertyInfo, fromValue, newValue); } else { if (this.Increment) { newValue = this.IncrementCurrentValue(propertyInfo); } propertyInfo.SetValue(this.Target, newValue, new object[0]); } } catch (FormatException e) { innerException = e; } catch (ArgumentException e) { innerException = e; } catch (MethodAccessException e) { innerException = e; } if (innerException != null) { throw new ArgumentException(string.Format( CultureInfo.CurrentCulture, ExceptionStringTable.ChangePropertyActionCannotSetValueExceptionMessage, this.Value != null ? this.Value.GetType().Name : "null", this.PropertyName, propertyInfo.PropertyType.Name), innerException); } }