如何从Convert获得ConvertBack参数?

时间:2017-08-03 13:19:34

标签: c# wpf mvvm imultivalueconverter

问题:

我正在使用MultiBinding转换器将(x,y)坐标传递给方法。

我不能让它向后退方向工作:

public class MyConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var x = (int)values[0];
        var y = (int)values[1];
        return Model.Get(x, y);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        Model.Set(x, y, value); // how to get x, y here?
        return new object[] { Binding.DoNothing, Binding.DoNothing };
    }
}

其他信息:

数据将以表格形式显示。这是单元格模板:

<TextBox>
    <TextBox.Text>
        <MultiBinding Converter="{StaticResource converter}" Mode="TwoWay">
            <Binding Path="X" Mode="OneWay" />
            <Binding Path="Y" Mode="OneWay" RelativeSource="..." />
        </MultiBinding>
    </TextBox.Text>
</TextBox>

我们的想法是使用转换器,它接收x(来自单元格视图模型)和y(来自父列视图模型,请注意RelativeSource)并调用Get(x,y)显示价值。

但是,当用户输入内容时,系统会调用ConvertBack,我需要调用Set(x, y, value)方法。

如何将xy传递到ConvertBack

3 个答案:

答案 0 :(得分:3)

可能会有或多或少的脏处理方法来使这样的多值转换器工作。但是我建议你保持你的多值转换器单向,但返回一个包装实际文本属性的容器对象。

不是直接绑定到TextBox.Text属性,而是绑定到其他属性(例如DataContextTag),然后将文本绑定到容器值。

小例子:

<TextBox Text="{Binding Value}">
    <TextBox.DataContext>
        <MultiBinding Converter="{StaticResource cMyConverter}">
            <Binding Path="X"/>
            <Binding Path="Y"/>
        </MultiBinding>
    </TextBox.DataContext>
</TextBox>

使用容器和转换器:

public class ValueProxy
{
    public int X { get; set; }
    public int Y { get; set; }

    public string Value
    {
        get { return Model.Get(X, Y); }
        set { Model.Set(X, Y, value); }
    }
}
public class MyConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var x = (int)values[0];
        var y = (int)values[1];
        return new ValueProxy { X = x, Y = y };
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return new object[] { Binding.DoNothing, Binding.DoNothing };
    }
}

答案 1 :(得分:0)

简短的回答是,您无法直接x方法中获取yConvertBack的值。 IMultiValueConverter Convert个多个值组成一个值。因此,ConvertBack方法将执行相反的操作:将单个值转换为多个值。

这完全取决于您的Model.Get(x,y)方法返回的内容。它需要返回一个足够独特的值,以便从中获取xy的单独值。

示例:为每对(x,y)创建唯一的字符串。

答案 2 :(得分:0)

将参数传递给ConvertBack似乎 hard 。这可能是有可能的,但是有一种解决方法,这使ConvertBack变得不必要。感谢@XAMlMAX的想法。

实现它的一种可能性(可能有更好的方法)是使用数据模板。我们可以将TextBlock.Text与某些视图模型绑定,而不是使用string进行多重绑定ContentControl.Content,此视图模型应该完成剩下的工作,包括Set(x, y, value)调用。

这是代码:

public class ViewModel
{
    public int X { get; set; }
    public int Y { get; set; }

    string _text;
    public string Text
    {
        get { return _text; }
        set
        {
            // this should be only called by the view
            _text = value;
            Model.Set(X, Y, value);
        }
    }

    public ViewModel(string text)
    {
        _text = text;
    }
}

public class MyConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var x = (int)values[0];
        var y = (int)values[1];
        return new ViewModel(Model.Get(x, y)) { X = x, Y = y };
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

并且xaml将成为

<ContentControl Focusable="False">
    <ContentControl.Content>
        <MultiBinding Converter="{StaticResource converter}">
            <Binding Path="X" />
            <Binding Path="Y" RelativeSource="..."/>
        </MultiBinding>
    </ContentControl.Content>
</ContentControl>

数据模板

<DataTemplate DataType="{x:Type local:ViewModel}">
    <TextBox Text="{Binding Text}" />
</DataTemplate>