Wpf MVVM绑定到可观察属性的属性
我试图弄清楚当绑定的中间层发生变化时,如何触发PropertyChangedEvent。我将从这里的一个例子开始:Wpf MVVM绑定到可观察属性的属性,wpf,c#-4.0,data-binding,mvvm,Wpf,C# 4.0,Data Binding,Mvvm,我试图弄清楚当绑定的中间层发生变化时,如何触发PropertyChangedEvent。我将从这里的一个例子开始: public class MainViewModel :NotificationObject // Main DataContext { public SubViewModel SubVM{get; {_subVM = value; RaisePropertyChanged("SubVM");}} // observable property public void
public class MainViewModel :NotificationObject // Main DataContext
{
public SubViewModel SubVM{get; {_subVM = value; RaisePropertyChanged("SubVM");}} // observable property
public void DoChangeSubVM()
{
SubVM = new SubViewModel(); // doing this will not update the egControl
}
}
public class SubViewModel : NotificationObject
{
public Sub2ViewModel Sub2VM {get; set{_sub2VM = value; RaisePropertyChanged("Sub2VM");}} // observable property
}
public class Sub2ViewModel : NotificationObject
{
public int SomeProp {get; set {_someProp = value; RaisePropertyChanged("SomeProp");} // observable property
}
在XAML中:
<EgControl name="egControl" Content={Binding SubVM.Sub2VM.SomeProp} />
现在,如果我更改Sub2VM属性,egControl不会自动使用新Sub2VM实例的SomeProp值进行更新。如果不需要手动从Sub2VM属性设置器引发所有Sub2ViewModel propertychanged事件,人们如何实现这一点
使用:Prism.NET4.0好的,不确定Prism,但一般来说,这三个类都应该实现属性更改通知。最简单的方法是使用INotifyPropertyChanged。因此,子视图模型应该更像:
public class SubViewModel : INotifyPropertyChanged
{
private Sub2ViewModel sub2vm;
public Sub2ViewModel Sub2VM
{
get
{
return sub2vm;
}
set
{
sub2vm = value;
OnPropertyChanged("Sub2VM");
}
}
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
如果没有属性更改通知,UI就不知道何时对绑定属性进行udpate
如果不需要手动从Sub2VM属性设置器引发所有Sub2ViewModel propertychanged事件,人们如何实现这一点
回答
您有几种可能性:
在setter中引发您说过要避免的所有属性更改事件。但这是一个值得考虑的有效策略。如果您知道哪些属性依赖于另一个属性的结果,那么对于许多属性,它们将需要在setter中引发属性更改
public class myViewModel
{
private string _FirstName
public string FirstName
{
get { return_FirstName };
set
{
_FirstName = value;
RaisePropertyChanged("FirstName");
RaisePropertyChanged("FullName");
}
}
}
构造新的ViewModel后,在方法中引发所有属性更改事件
public class myViewModel
{
private string _FirstName
public string FirstName
{
get { return_FirstName };
set
{
_FirstName = value;
RaisePropertyChanged("FirstName");
}
}
public void UpdateFirstName(string firstName)
{
_FirstName = firstName;
RaisePropertyChanged("FirstName");
RaisePropertyChanged("FullName");
}
}
使用setter设置一些属性,从而触发已经存在的属性更改事件
public class myViewModel
{
private string _FirstName
public string FirstName
{
get { return_FirstName };
set
{
_FirstName = value;
RaisePropertyChanged("FirstName");
}
}
public Person ClonePerson(Person rootPerson)
{
Person clone = new Person()
{
FirstName = rootPerson.FirstName;
LastName = rootPerson.LastName;
}
return clone;
}
}
创建一个引发所有属性更改事件的方法,并在需要引发多个更改事件的边缘情况下调用该方法
public class myViewModel
{
private string _FirstName
public string FirstName
{
get { return_FirstName };
set
{
_FirstName = value;
this.RaiseAllPropertyChanges();
}
}
public void RaiseAllPropertyChanges()
{
RaisePropertyChanged("FirstName");
RaisePropertyChanged("FullName");
}
}
最终的结果是:要使任何绑定的UI元素知道它必须更新,必须引发该属性的property changed事件。一种方法是为SubViewModel和Sub2ViewModel创建一个构造函数,将所有属性初始化为某个默认值。这将确保您的属性已初始化,并使您能够设置初始值。所有这些类都继承自NotificationObject,它实现了INotifyPropertyChanged对象。我将更新该示例,使其更具体—该值应该更改。你可能做错了什么,但是除非你发布了你的实际代码,否则没有什么好说的。你是对的。默认情况下,它确实会这样做。我有一个代码,其中一个可观察属性正在访问子对象中的另一个op(与我发布的问题不同)。我通过订阅子对象属性changed并引发主属性changed事件来修复它。谢谢