Wpf OnPropertyChanged的替代方案
我试图解决在WPF中实现MVVM时遇到的一个问题。下面我的Wpf OnPropertyChanged的替代方案,wpf,mvvm,inotifypropertychanged,Wpf,Mvvm,Inotifypropertychanged,我试图解决在WPF中实现MVVM时遇到的一个问题。下面我的Contact类是由实体框架填充的我的模型 public class Contact : INotifyPropertyChanged { public string _firstName; public string FirstName { get { return _firstName; } set {
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;
}
}
}
因此,我将视图的数据源设置为ContactViewModel
的一个实例,并将两个文本框绑定到MyContact.FirstName
和MyContact.LastName
。我正在将文本块
绑定到全名
。当我更改任一文本框时,全名TextBlock
不会更新(显然,我没有在任何地方执行OnPropertyChanged(“全名”)
)
问题是,我在哪里添加OnPropertyChanged(“全名”)
我不一定要修改我的模型,因为它正在其他地方使用,我不想将它绑定到我的ViewModel。
我需要重新思考我的架构吗
我需要重新思考我的架构吗
这可以通过您当前的体系结构来解决。您只需要将调用从联系人
对象传播到viewModel对象
您需要在viewModel中实现INotifyPropertyChanged
,才能实现这一点
大概是这样的:
我还建议大家看一看,因为这包括一个名为PropertyObserver
的类,它的设计目的是使这类事情的连接更加容易
如果您想采用Big Daddy建议的更纯粹的MVVM方法,您需要执行以下操作:
我需要重新思考我的架构吗
这可以通过您当前的体系结构来解决。您只需要将调用从联系人
对象传播到viewModel对象
您需要在viewModel中实现INotifyPropertyChanged
,才能实现这一点
大概是这样的:
我还建议大家看一看,因为这包括一个名为PropertyObserver
的类,它的设计目的是使这类事情的连接更加容易
如果您想采用Big Daddy建议的更纯粹的MVVM方法,您需要执行以下操作:
也许
在我看来,您正在将视图的属性绑定到视图模型(ContactViewModel)和模型(Contact)。您的视图可以通过视图模型查看公共模型的属性等-我认为这不好。这似乎违反了德米特法。我宁愿看到您使用视图模型作为模型的包装器/外观。这无疑会带来更多的工作,但我认为这会给您带来更好的设计和更大的灵活性。视图模型需要实现INotifyPropertyChanged
,才能工作
也许
在我看来,您正在将视图的属性绑定到视图模型(ContactViewModel)和模型(Contact)。您的视图可以通过视图模型查看公共模型的属性等-我认为这不好。这似乎违反了德米特法。我宁愿看到您使用视图模型作为模型的包装器/外观。这无疑会带来更多的工作,但我认为这会给您带来更好的设计和更大的灵活性。您的视图模型需要实现
INotifyPropertyChanged
,才能正常工作。问题是:我不一定要修改我的模型,因为它正在其他地方使用,我不需要将它绑定到我的视图模型。因此,当任何属性发生更改时,这将触发OnPropertyChanged(“全名”),而不仅仅是FirstName或LastName,正确吗?@MikeCole是的,但如果您想避免,只需在属性更改处理程序中添加一个if(e.PropertyName==“FirstName”| | e.PropertyName==“LastName”)
检查即可。(另外,在尝试连接和分离setter中的属性已更改的处理程序之前,您需要检查myContact
是否为null
)@Mike Cole-Rachel说的话^@Rachel我想这是您今天第二次帮助我,谢谢!问题是:我不一定要修改我的模型,因为它正在其他地方使用,我不想将它绑定到我的ViewModel。因此,当任何属性发生更改时,这将触发OnPropertyChanged(“全名”),而不仅仅是FirstName或LastName,对吗?@MikeCole是的,但如果您想避免,只需添加一个if(e.PropertyName==“FirstName”| e.PropertyName==“LastName”)
检查属性更改处理程序。(此外,在尝试附加和分离setter中的属性更改处理程序之前,您还需要检查\u myContact
是否为null
)@Mike Cole-Rachel说的话^@Rachel我想这是你今天第二次帮助我了,谢谢!通常是ViewModel实现了INPC接口,而不是模型。如果是这样的话,我该如何绑定到我的模型?有些人复制了他们ViewModel上的属性。这些属性包装了模型和视图上的属性仅绑定到您的viewModel。这两种方法都是有效的。确切地说,viewModel只包含需要由视图显示或操作的属性。VM中的属性使用模型的属性作为其支持字段。通常是viewModel实现INPC接口,而不是模型。如果是这种情况,如何d我绑定到我的模型?有些人复制他们的viewModel上的属性。这些属性包装模型上的属性,而您的视图仅绑定到您的viewModel。这两种方法都是有效的。确切地说,viewModel只包含需要视图显示或操纵的属性。VM中的属性使用t的属性他将模型作为他们的支持字段。问题是我的模型实现了IDataErrorInfo并进行了验证。现在,这将传递到我的视图中,并被优雅地处理。如果映射到ViewModel的属性,我会丢失这些验证规则吗?P
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");
}
}
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?