可绑定转换器和转换器参数的修订





5.00/5 (2投票s)
这是“可绑定转换器参数”的替代方案。
引言
文章 https://codeproject.org.cn/Articles/459958/Bindable-Converter-and-Converter-Parameter 由 Henrik Jonsson 撰写,帮我解决了问题。
我只是想贡献代码,使其更加健壮....
使用代码
这是在 XAML 中的用法
<TextBox
Text="{myNameSpace:BindableConverter
Binding={Binding Path=...},
ConverterBinding={Binding Path=...},
UpdateSourceTrigger=PropertyChanged}" />
标记扩展变为
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);
}
}
适配器变为
public class BindableConverterAdapter : IMultiValueConverter
{
public IValueConverter Converter { get; set; }
public object ConverterParameter { get; set; }
#region IMultiValueConverter Members
/// <summary>
/// ConverterBinding and ConverterParameterBinding take
/// precedence over respectively Converter and ConverterParameter
/// </summary>
<returns>public object Convert(object[] values, Type targetType,
object parameter, CultureInfo culture)
{
//values [0]: Binding
//values [1]: IValueConverter or BindingParameter
//values [2]: only BindingParameter
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
}