OnPropertyChanged的替代品

时间:2013-05-10 18:13:39

标签: wpf mvvm inotifypropertychanged

我正在尝试解决我在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.FirstNameMyContact.LastName。我将TextBlock绑定到FullName。当我更改我的任一文本框时,全名TextBlock不会更新(显然,我在任何地方都没有OnPropertyChanged("FullName"))。

问题是,我应该在哪里添加OnPropertyChanged("FullName")我不一定要修改我的模型,因为它正在其他地方使用,我不会将它与我的ViewModel联系起来。

我是否需要重新考虑我的架构?

2 个答案:

答案 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才能实现此目的。