Introduction
The article http://www.codeproject.com/Articles/459958/Bindable-Converter-and-Converter-Parameter written
by Henrik Jonsson saved my day.
I just wanted to contribute making the code more robust....
Using the code
This is the usage in the XAML:
<TextBox
Text="{myNameSpace:BindableConverter
Binding={Binding Path=...},
ConverterBinding={Binding Path=...},
UpdateSourceTrigger=PropertyChanged}" />
The Markup extension becomes:
public class BindableConverter : MarkupExtension
{
public Binding Binding { get; set; }
public IValueConverter Converter { get; set; }
public Binding ConverterBinding { get; set; }
public object ConverterParameter { get; set; }
public Binding ConverterParameterBinding { get; set; }
public UpdateSourceTrigger UpdateSourceTrigger { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (Converter == null && ConverterBinding == null)
throw new Exception("Neither Converter nor ConverterBinding where provided");
if (ConverterBinding == null && ConverterParameterBinding == null)
throw new Exception("There is no point using this Extension. Please use standard Binding");
MultiBinding multiBinding = new MultiBinding();
multiBinding.UpdateSourceTrigger = UpdateSourceTrigger;
multiBinding.Bindings.Add(Binding);
if (ConverterBinding != null)
multiBinding.Bindings.Add(ConverterBinding);
if (ConverterParameterBinding != null)
multiBinding.Bindings.Add(ConverterParameterBinding);
BindableConverterAdapter adapter = new BindableConverterAdapter();
adapter.Converter = Converter;
adapter.ConverterParameter = ConverterParameter;
multiBinding.Converter = adapter;
return multiBinding.ProvideValue(serviceProvider);
}
}
And the Adapter becomes:
public class BindableConverterAdapter : IMultiValueConverter
{
public IValueConverter Converter { get; set; }
public object ConverterParameter { get; set; }
#region IMultiValueConverter Members
<returns>public object Convert(object[] values, Type targetType,
object parameter, CultureInfo culture)
{
IValueConverter converterBinding = values[1] as IValueConverter;
if (converterBinding != null)
{
Converter = converterBinding;
if (values.Length > 2)
ConverterParameter = values[2];
}
else
ConverterParameter = values[1];
return Converter.Convert(values[0], targetType, ConverterParameter, culture);
}
public object[] ConvertBack(object value, Type[] targetTypes,
object parameter, CultureInfo culture)
{
return new[] {Converter.ConvertBack(value, targetTypes[0], null, culture)};
}
#endregion
}