如何从转换中获取转换回来参数?



问题:

我正在使用带有转换器的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

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

与其直接绑定到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 };
}
}

简短的回答是,您无法ConvertBack方法中直接获取xy的值。IMultiValueConverterConvert多个值合并为单个值。因此,ConvertBack方法将执行相反的操作:将单个值转换为多个值。

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

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

似乎很难将参数传递到ConvertBack中。这可能是可能的,但有一个解决方法,这使得ConvertBack没有必要。感谢@XAMlMAX的想法。

实现它的一种可能性(可能有更好的方法(是使用数据模板。我们可以将ContentControl.Content与某个视图模型绑定,而不是与string进行多重绑定TextBlock.Text,这个视图模型应该完成其余的工作,包括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>

相关内容

  • 没有找到相关文章

最新更新