MVVM-Light Toolkit - 如何使用PropertyChangedMessage

时间:2012-11-19 20:03:37

标签: wpf mvvm-light

有人可以发布正在使用的PropertyChangedMessage的工作示例吗? GalaSoft网站的描述指出:

  

PropertyChangedMessage:用于广播发件人中更改的属性。实现与PropertyChanged事件相同的目的,但不太紧张。

但是,这似乎不起作用:

private bool m_value = false;
public bool Value
{
    get { return m_value ; }
    set 
    { 
        m_value = value;
        Messenger.Default.Send(new PropertyChangedMessage<bool>(m_value, true, "Value"));
    }

2 个答案:

答案 0 :(得分:6)

这与MVVM Light Messenger有关。

在您的属性定义中,您可以这样使用:

public string Name {
    get
    {
        return _name;
    }
     set
    {
        if (_name == value)
        {
            return;
        }
         var oldValue = _name;
        _name = value;
         // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
        RaisePropertyChanged(Name, oldValue, value, true);
    }
}

然后您可以使用以下内容对该属性进行任何修改:

Messenger.Default.Register<PropertyChangedMessage<string>>(
    this, (e) => this.Name = e.NewValue
);

查看此post并阅读MVVM Light Messenger

播出:

Messenger.Default.Send<PropertyChangedMessage<string>>(oldValue, newValue, "PropertyName");

答案 1 :(得分:4)

丹尼尔·卡斯特罗用以下问题对我的问题发表了评论:“你对代码有什么期望?”

这个问题的答案促使我把这个答案写在我自己的问题上。

我的期望是,基于MVVM-Light文档中对PropertyChangedMessage类的错误编写的描述,当我发送一个PropertyChangedMessage时,ViewModelBase类上的RaisePropertyChanged方法将自动被调用。

然而,显然,情况恰恰相反。当您调用RaisePropertyChanged时,该方法有一个重载,您可以设置一个标志来确定是否将发送PropertyChangedMessage。

但是,我想要我最初期望的功能。我想发送一个新的PropertyChangedMessage,它会自动调用RaisePropertyChanged。这是如何做到的。

使用以下公共NotifyPropertyChanged方法从ViewModelBase派生一个新类,该方法只调用受保护的RaisePropertyChanged方法:

public abstract class MyViewModelBase : GalaSoft.MvvmLight.ViewModelBase
{
    public void NotifyPropertyChanged(string propertyName)
    {
        RaisePropertyChanged(propertyName);
    }
}

然后从PropertyChangedMessage派生一个新类,该类调用新的NotifyPropertyChanged方法:

public class MyPropertyChangedMessage<T> : PropertyChangedMessage<T>
{
    public MyPropertyChangedMessage(object sender, T oldValue, T newValue, string propertyName)
        : base(sender, oldValue, newValue, propertyName)
    {
        var viewModel = sender as MyViewModelBase;

        if (viewModel != null)
        {
            viewModel.NotifyPropertyChanged(propertyName);
        }
    }

    public MyPropertyChangedMessage(object sender, object target, T oldValue, T newValue, string propertyName)
        : base(sender, target, oldValue, newValue, propertyName)
    {
        var viewModel = sender as MyViewModelBase;

        if (viewModel != null)
        {
            viewModel.NotifyPropertyChanged(propertyName);
        }
    }
}

我已经测试了这种方法并验证我确实可以编写如下代码,这会导致UI正确更新:

private bool m_value = false;
public bool Value
{
    get { return m_value; }
    set
    {
        Messenger.Default.Send(new MyPropertyChangedMessage<bool>(this, m_value, value, "Value"));
        m_value = value;
    }
}