我正试图解决在WPF中实现MVVM时遇到的一个问题。下面的Contact
类是由实体框架填充的模型。
public class Contact : INotifyPropertyChanged
{
public string _firstName;
public string FirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
OnPropertyChanged("FirstName");
}
}
public string _lastName;
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
OnPropertyChanged("LastName");
}
}
//INotifyPropertyChanged implementation omitted for brevity
}
这是我的ViewModel:
public class ContactViewModel
{
public Contact MyContact { get; set; }
public string FullName
{
get
{
return MyContact.FirstName + " " + MyContact.LastName;
}
}
}
因此,我将View的数据源设置为ContactViewModel
的实例,并将两个TextBox绑定到MyContact.FirstName
和MyContact.LastName
。我正在将TextBlock
绑定到FullName
。当我更改任何一个文本框时,全名TextBlock
都不会更新(显然,我不会在任何地方执行OnPropertyChanged("FullName")
(。
问题是,我在哪里添加OnPropertyChanged("FullName")
我不一定要修改我的模型,因为它正在其他地方使用,而且我不想将它与我的ViewModel绑定
我需要重新思考我的架构吗?
我需要重新思考我的体系结构吗
这可以通过您当前的体系结构来解决。您只需要将调用从Contact
对象传播到viewModel对象。
您需要在viewModel中实现INotifyPropertyChanged
才能实现这一点。
类似这样的东西:
public class ContactViewModel : INotifyPropertyChanged
{
//INotifyPropertyChanged implementation omitted for brevity...
private Contact _myContact;
public Contact MyContact
{
get
{
return _myContact;
}
set
{
_myContact.PropertyChanged -= myHandler;
_myContact = value;
_myContact.PropertyChanged += myHandler;
}
}
public string FullName
{
get
{
return MyContact.FirstName + " " + MyContact.LastName;
}
}
private void myHandler(Object sender, PropertyChangedEventArgs e)
{
OnPropertyChanged("FullName");
}
}
我还建议查看MVVM Foundation,因为它包括一个名为PropertyObserver
的类,该类旨在使这类事情的连接更加容易。
如果你想采用Big Daddy建议的更纯粹的MVVM方法,你需要做一些之类的事情:
public class ContactViewModel : INotifyPropertyChanged
{
// INotifyPropertyChanged implementation omitted for brevity...
// You will require some way of setting this, either via a property
// or the viewModel constructor...
private Contact _myContact;
public string FirstName
{
get { return _myContact.FirstName; }
set
{
_myContact.FirstName = value;
OnPropertyChanged("FirstName");
OnPropertyChanged("FullName");
}
}
public string LastName
{
get { return _myContact.LastName; }
set
{
_myContact.LastName = value;
OnPropertyChanged("LastName");
OnPropertyChanged("FullName");
}
}
public string FullName
{
get
{
return MyContact.FirstName + " " + MyContact.LastName;
}
}
}
Do I need to rethink my architecture?
也许。。。
在我看来,您正在将视图的属性绑定到视图模型(ContactViewModel(和模型(Contact(。你的视图可以通过你的视图模型看到你的公共模型的属性等等——我认为这不好。这看起来违反了Law of Demeter
。我更希望您使用视图模型作为模型的包装器/外观。这肯定会带来更多的工作,但我认为它会给你更好的设计和更大的灵活性。您的视图模型需要实现INotifyPropertyChanged
才能工作。