我有一位模特用户:
public class User
{
public string Name { get; set; }
public int Level { get; set; }
}
在视图中:
<TextBox Text="{Binding NewUser.Name}"/>
<TextBox Text="{Binding NewUser.Level}"/>
和VM中的属性:
public User NewUser
{
get { return _newUser; }
set
{
if (_newUser == value)
return;
_newUser = value;
RaisePropertyChanged("NewUser");
}
}
此代码确实更新了属性:
NewUser = new User() { Name = "test", Level = 1 };
此代码不会:
NewUser.Name = "test";
答案 0 :(得分:2)
设置NewUser.Name
时,未调用ViewModel上的RaisePropertyChanged
,因此不会触发PropertyChangedEvent
。
通常,您应该有充分的理由直接在ViewModel中公开模型类,就像在此处一样(在ViewModel中将User
模型公开为公共属性)。这基本上违反了模型和ViewModel之间关注点的分离,MVVM就是为此而设计的。虽然它似乎是学术性的,但我的经验是,在这里保持清洁是非常值得的,因为在大多数现实世界中,ViewModel随着时间的推移往往会变得更加复杂,并且包含您不希望在模型中使用的功能(像INPC实现,顺便说一句。
虽然它涉及更多编码,但您应该在此处实现嵌套的ViewModel。这里有一些代码可以帮助您入门:
public class ParentViewModel : NotifyingObject
{
private UserViewModel _user;
// This is the property to bind to
public UserViewModel User
{
get { return _user; }
private set
{
_user = value;
RaisePropertyChanged(() => User);
}
}
public ParentViewModel()
{
// Wrap the new instance in a ViewModel
var newUser = new User {Name = "Test"};
User = new UserViewModel(newUser);
}
}
这是包含User
模型类的额外ViewModel:
public class UserViewModel : NotifyingObject
{
/// <summary>
/// The model is private here and not exposed to the view
/// </summary>
private readonly User _model;
public string Name
{
get { return _model.Name; }
set
{
_model.Name = value;
RaisePropertyChanged(() => Name);
}
}
public UserViewModel(User model)
{
_model = model;
}
}
这是你的模特课。无需实施INotifyPropertyChanged
。
public class User
{
public string Name { get; set; }
}
答案 1 :(得分:1)
您没有为INotifyPropertyChanged
课程实施User
。因此,通过赋值更改属性NewUser将触发UI,通过赋值设置属性Name不会。
如果你按照你的模式,这个:
public string Name { get; set; }
最终应该是这样的:
public string Name
{
get { return _name; }
set
{
if (_name == value)
return;
_name = value;
RaisePropertyChanged("Name");
}
}