如何使用IValueConverter绑定到WPF中对象的不同属性?

时间:2015-08-25 03:03:02

标签: c# wpf

我的视图模型中有一个属性,它具有一个具有多个属性的类的属性,例如

public class Content
{
    public int Selector { get; set; }
    public int Value1 { get; set; }
    public int Value2 { get; set; }
    public int Value3 { get; set; }
    public int Value4 { get; set; }
}

public class ViewModel
{
    public Content ContentInstance { get; set; }
}

我希望在我的xaml中用转换器绑定它,使得选择器的值确定哪个值绑定到元素,例如

<TextBox Text="{Binding ContentInstance, Converter="ContentValueConverter", TargetNullValue='', Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

到目前为止,我有:

public class ContentValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)    
    {
        var contentPart = value as Content;
        if(contentPart == null) return;

        switch(contentPart.Selector)
        {
            case 1:
                return contentPart.Value1;
            //etc
        }
    }

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

这可以显示值,但不会将值保存回模型。 我宁愿将其保留在IValueConverter中,因为必须将其添加到代码库中的许多位置。任何有助于将价值节省回到模型的帮助都将受到赞赏。

2 个答案:

答案 0 :(得分:0)

将文本框绑定到每个属性并将它们放在同一网格列/行中。使用转换器将它们的可见性绑定到selector属性,该转换器将选择器的哪个值使其可见。现在,您的可见文本框绑定到正确的属性,并由您的选择器选择控制。您可以通过将其放在单独的UserControl或ControlTemplate中来使其可重用。

答案 1 :(得分:0)

您的方法还有一个缺陷 - 即使Content实现Content,WPF也不会对任何INotifyPropertyChanged属性进行任何更改。

如果您不关心,理论上,根据您的方案,您可以存储对Content方法传递给Convert方法的引用,并在ConvertBack中重复使用它。它不是很干净也不是WPFish,每个绑定需要一个单独的转换器实例(因此转换器必须内联定义,而不是作为资源定义)。

那么为什么不在ViewModel中实现代理属性呢?

public class ViewModel
{
    public Content ContentInstance { get; set; }
    public int Value
    {
        get
        {
            switch (Content.Selector)
            {
                case 1:
                    return contentPart.Value1;
                //etc
            }
        }
        set
        {
            switch (Content.Selector)
            {
                case 1:
                    contentPart.Value1 = value;
                    break;
                //etc
            }
        }
    }
}

然后你可以直接绑定它:

<TextBox Text="{Binding Value, Mode=TwoWay}"/>

清洁有效。如果您的Content实施INotifyPropertyChanged,则ViewModel可以拦截它并为Value属性提升已更改的事件。