Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
            }
        }