65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2013年9月9日

CPOL
viewsIcon

9679

这是“可绑定转换器参数”的替代方案。

引言

文章 https://codeproject.org.cn/Articles/459958/Bindable-Converter-and-Converter-Parameter 撰写,帮我解决了问题。

我只是想贡献代码,使其更加健壮....

使用代码

这是在 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
}
© . All rights reserved.