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(); } 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); }
/// <summary> /// This method evaluates operands. /// </summary> /// <param name="leftOperand">Left operand from the LeftOperand property.</param> /// <param name="operatorType">Operator from Operator property.</param> /// <param name="rightOperand">Right operand from the RightOperand property.</param> /// <returns>Returns true if the condition is met; otherwise, returns false.</returns> internal static bool EvaluateImpl(object leftOperand, ComparisonConditionType operatorType, object rightOperand) { bool result = false; if (leftOperand != null) { Type leftType = leftOperand.GetType(); if (rightOperand != null) { TypeConverter typeConverter = TypeConverterHelper.GetTypeConverter(leftType); rightOperand = TypeConverterHelper.DoConversionFrom(typeConverter, rightOperand); } } IComparable leftComparableOperand = leftOperand as IComparable; IComparable rightComparableOperand = rightOperand as IComparable; // If both operands are comparable, use arithmetic comparison if (leftComparableOperand != null && rightComparableOperand != null) { return(ComparisonLogic.EvaluateComparable(leftComparableOperand, operatorType, rightComparableOperand)); } switch (operatorType) { case ComparisonConditionType.Equal: result = object.Equals(leftOperand, rightOperand); break; case ComparisonConditionType.NotEqual: result = !object.Equals(leftOperand, rightOperand); break; case ComparisonConditionType.GreaterThan: case ComparisonConditionType.GreaterThanOrEqual: case ComparisonConditionType.LessThan: case ComparisonConditionType.LessThanOrEqual: if (leftComparableOperand == null && rightComparableOperand == null) { throw new ArgumentException(); } else if (leftComparableOperand == null) { throw new ArgumentException(); } else { throw new ArgumentException(); } } return(result); }
private object IncrementCurrentValue(PropertyInfo propertyInfo) { if (!propertyInfo.CanRead) { throw new InvalidOperationException(); } 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); }
internal static object DoConversionFrom(TypeConverter converter, object value) { object returnValue = value; try { if (converter != null && value != null && converter.CanConvertFrom(value.GetType())) { // This utility class is used to convert value that come from XAML, so we should use the invariant culture. returnValue = converter.ConvertFrom(context: null, culture: CultureInfo.InvariantCulture, value: value); } } catch (Exception e) { if (!TypeConverterHelper.ShouldEatException(e)) { throw; } } 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(); } }