RaisePropertyChanged用于对象的属性

时间:2014-08-14 06:11:28

标签: wpf object properties mvvm-light inotifypropertychanged

我有一位模特用户:

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";

我在做错了什么?我正在使用mvvm light。

2 个答案:

答案 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");
    }
}