我想绑定到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
类的属性发生更改,我天真地期望绑定会被警告。显然它不是......有一个好的模式(或者,希望是一个简单的解决方法)来处理这种情况吗?
答案 0 :(得分:1)
如果我是你,当PropertyChanged("MyPoco")
的任何属性发生变化时(或者应该假定已经更改,或者其他任何属性),我只是让父虚拟机加注MyPoco
情况是)。这将导致绑定更新目标,并且将调用转换器的Convert
。
替代方案将涉及您必须编写和调试和维护的C#代码,在XAML绑定到属性值对象的属性的情况下,这是使用INotifyPropertyChanged
的完全正常的方式。 #39;是不可变的,或者没有实现INotifyPropertyChanged
。例如,我已经绑定StringProperty.Length
几次,或NullableProperty.HasValue
。