我正在尝试解决我在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联系起来。
我是否需要重新考虑我的架构?
答案 0 :(得分:3)
我是否需要重新考虑我的架构?
这可以通过您当前的架构来解决。您只需将调用从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;
}
}
}
答案 1 :(得分:1)
Do I need to rethink my architecture?
也许......
在我看来,您将视图的属性绑定到视图模型(ContactViewModel)和您的模型(联系人)。您的视图可以通过您的视图模型查看您的公共模型的属性等 - 我认为这不是很好。它看起来违反了Law of Demeter
。我宁愿看到你使用你的视图模型作为模型的包装/外观。这确实创造了更多的工作,但我认为它为您提供了更好的设计和更大的灵活性。您的视图模型需要实现INotifyPropertyChanged
才能实现此目的。