使用IMultiValueConverter进行多路分解

时间:2014-11-20 16:23:22

标签: c# wpf xaml

我有一个DependencyProperty X(String)和n DependencyProperties Yi(String),所有类型都是String,其中X是所有i的Yi的串联。使用MultiValueConverter可以轻松实现这一目标。

另一方面,如果x发生变化,我想将x拆分成块,并将每个块(通过一些依赖于块的数据值的规则集)分配给相应的y_i。

为此,我需要知道ConvertBack返回的Object []的哪个索引j连接到y_i。

所以我想知道:我如何获得对其属性的源对象的引用,其中指定了ConvertBack中返回的Object []中的第j个值

我的转换方法:

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        StringBuilder b = new StringBuilder();
        String cur;

        for (Int32 i = 0; i < values.Length; i++)
        {
            if(String.IsNullOrEmpty(cur = values[i] as String)) continue;

            if (b.Length != 0) b.Append(',');
            b.Append(cur);
        }

        return b.ToString();
    }

和相应的ConvertBack

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        Object[] ret = new Object[targetTypes.Length];

        // How do I know which Source.Property the element
        // ret[i]
        // targets

    }

1 个答案:

答案 0 :(得分:0)

我发现了一个适用于我的通用(并且有点实用)的解决方案

我在IMultiValueConverter中实现了ConvertBack,如下所示

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
    Object[] ret = new Object[targetTypes.Length];

    if(null != (value as String))
        for(Int32 i = 0; i < targetType.Length; i++)
        {
            // Propagate a copy of value to each Binding
            ret[i] = value.ToString();
        }

    return ret;
}

这将为每个附加的Yi分配提供的值。由于MultiBinding是Binding-s的“集合”,因此可以将IValueConverter附加到每个Binding。每个IValueConverter都可以使用一些有关其附加源的信息进行参数化,因此它可以过滤掉任何不属于附加源的块。

附上一个IValueConverter示例,它使用参数提供的数据来过滤掉值

[ValueConversion(typeof(String), typeof(String))]
public sealed class ParameterFilter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if(null == (parameter as String)) return DependencyProperty.UnsetValue;
        if(null == (value as String)) return DependencyProperty.UnsetValue;

        String[] split = value.ToString().Split(',');
        StringBuilder b = new StringBuilder();
        String cur;

        for (Int32 i = 0; i < split.Length; i++)
        {
            if(String.IsNullOrEmpty(cur = split[i])) continue;
            if(!cur.Contains(parameter.ToString()) continue;

            if (b.Length != 0) b.Append(',');
            b.Append(cur);
        }

        return b.ToString();
    }
}