/// <summary> /// Modifies the target data before passing it to the source object. This method is called only in <see cref="F:System.Windows.Data.BindingMode.TwoWay" /> bindings. /// </summary> /// <param name="value">The target data being passed to the source.</param> /// <param name="targetType">The <see cref="T:System.Type" /> of data expected by the source object.</param> /// <param name="parameter">An optional parameter to be used in the converter logic.</param> /// <param name="culture">The culture of the conversion.</param> /// <returns>The value to be passed to the source object.</returns> object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { var converter = Converter; if (converter == null) return value; var converterParameter = ConverterParameter; SourceValuesErrors = null; try { var multiValueConverter = converter as IMultiValueConverter; if (multiValueConverter != null) { // Guess target types based on current source values var targetTypes = new Type[m_sourceCount]; for (var i = 0; i < targetTypes.Length; i++) { var currentValue = Target.GetValue(dataProperties[m_sourceStartIndex + i]); targetTypes[i] = currentValue != null ? currentValue.GetType() : typeof(Object); } var convertedValues = multiValueConverter.ConvertBack(value, targetTypes, converterParameter, culture); return convertedValues; } var valueConverter = converter as IValueConverter; if (valueConverter != null) { var convertedValue = valueConverter.ConvertBack(value, targetType, converterParameter, culture); return convertedValue != DependencyProperty.UnsetValue ? new object[] { convertedValue } : convertedValue; } } catch (Exception ex) { SourceValuesErrors = new MultiBindingValidationError[] { new MultiBindingValidationError(ex) }; if (MultiBinding.ValidatesOnExceptions) { return DependencyProperty.UnsetValue; } throw; } return value; }
/// <summary> /// Modifies the source data before passing it to the target for display in the UI. /// </summary> /// <param name="value">The source data being passed to the target.</param> /// <param name="targetType">The <see cref="T:System.Type" /> of data expected by the target dependency property.</param> /// <param name="parameter">An optional parameter to be used in the converter logic.</param> /// <param name="culture">The culture of the conversion.</param> /// <returns>The value to be passed to the target dependency property.</returns> object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value == null) return DependencyProperty.UnsetValue; var unconvertedValues = (object[])value; var converter = Converter; object result = unconvertedValues; if (converter != null) { var converterParameter = ConverterParameter; SourceValuesErrors = null; try { var multiConverter = converter as IMultiValueConverter; if (multiConverter != null) { result = multiConverter.Convert(unconvertedValues, targetType, converterParameter, culture); } else { var singleConverter = converter as IValueConverter; if (singleConverter != null) { result = singleConverter.Convert(unconvertedValues[0], targetType, converterParameter, culture); } } } catch (Exception ex) { SourceValuesErrors = new MultiBindingValidationError[] { new MultiBindingValidationError(ex) }; if (MultiBinding.ValidatesOnExceptions) { return DependencyProperty.UnsetValue; } throw; } } if (result != DependencyProperty.UnsetValue) { var format = StringFormat; if (format != null) { format = Regex.Replace(format, @"%(\d+)", "{$1}"); if (result is Object[]) { result = String.Format(culture, format, result); } else { result = String.Format(culture, format, result); } } } return result; }