嵌套属性的更改通知模式

时间:2016-10-27 15:43:57

标签: c# wpf data-binding

我想绑定到ViewModel属性的属性。嵌套对象在编译时是未知的,因此我不能直接将绑定路径设置为其属性之一。相反,我作为一个整体绑定到对象,值转换器使用反射搜索感兴趣的属性(或属性)。

绑定和值转换器最初工作正常,但如果嵌套属性的值被更改,则不会调用值转换器(如果在VM中更改了对此对象的引用)。 VM和嵌套类都实现INotifyPropertyChanged

这是一个简化的示例,其中Name的值最初设置为" Bond"秘密被揭露,但是如果组合框的价值被改变为"邦德"程序运行时:

XAML:

<Window.Resources>
    <local:ViewModel x:Key="vm" />
    <local:NameToVisConverter x:Key="NameToVis" />
</Window.Resources>

<StackPanel DataContext="{StaticResource vm}">
    <ComboBox SelectedValue="{Binding MyPoco.Name}">
        <sys:String>Smith</sys:String>
        <sys:String>Jones</sys:String>
        <sys:String>Bond</sys:String>
    </ComboBox>

    <Label Visibility="{Binding MyPoco, Converter={StaticResource NameToVis}}">
        Secret!
    </Label>
</StackPanel>

ViewModel&amp;嵌套类:

public class ViewModel : BindableBase
{
    public Poco MyPoco
    {
        get { return _MyPoco; }
        set { SetProperty(ref _MyPoco, value); }
    }
    private Poco _MyPoco = new Poco();
}

public class Poco : BindableBase
{
    public String Name
    {
        get { return _Name; }
        set { SetProperty(ref _Name, value); }
    }
    private String _Name;

}

注意: BindableBase及其SetProperty()由Prism提供并实施INotifyPropertyChanged

NameToVisConverter的价值转换方法:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    return (value as Poco).Name == "Bond"
        ? Visibility.Visible
        : Visibility.Collapsed;
}

如果绑定在对象本身而不是对象的某个属性上,如果INotifyPropertyChanged类的属性发生更改,我天真地期望绑定会被警告。显然它不是......有一个好的模式(或者,希望是一个简单的解决方法)来处理这种情况吗?

1 个答案:

答案 0 :(得分:1)

如果我是你,当PropertyChanged("MyPoco")的任何属性发生变化时(或者应该假定已经更改,或者其他任何属性),我只是让父虚拟机加注MyPoco情况是)。这将导致绑定更新目标,并且将调用转换器的Convert

替代方案将涉及您必须编写和调试和维护的C#代码,在XAML绑定到属性值对象的属性的情况下,这是使用INotifyPropertyChanged的完全正常的方式。 #39;是不可变的,或者没有实现INotifyPropertyChanged。例如,我已经绑定StringProperty.Length几次,或NullableProperty.HasValue