3

有人可以发布一个正在使用的 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"));
    }
4

2 回答 2

7

这与 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
);

查看这篇文章并阅读有关MVVM Light Messenger的信息

广播:

Messenger.Default.Send<PropertyChangedMessage<string>>(oldValue, newValue, "PropertyName");
于 2012-11-19T20:14:55.227 回答
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;
    }
}
于 2012-11-19T21:06:25.907 回答