通过MVVMLight发送命令

时间:2011-09-16 14:44:06

标签: mvvm-light

我正在使用MVVMLight,并通过一些学习曲线来尝试解决通信的工作原理。我理解Properties如何与Silverlight绑定一起工作,这一切都非常简单。

现在我想知道的是发送消息作为命令的最佳方法是什么。例如,我想向我的ViewModel发送一条消息来删除它的列表。

所以我可以创建一个枚举来充当命令

enum MessageOp
{
    Reset
}

但是我怎么能把它作为命令发送?目前我发送它作为类,但然后需要再次作为令牌发送它。像这样:

Messenger.Default.Send<MessageOp>(MessageOp.Reset, MessageOp.Reset);

我在ViewModel中的代码如下:

Messenger.Default.Register<MessageOp>(
    this, MessageOp.Reset,
    delegate(MessageOp op)
    {
        // Erase all entries
        MyDictionary.Clear();
    });

我想到的一种方法是创建一个完全空的类来充当命令。这会是最好的方法,因为我觉得有点奇怪创建空类来像这样行事

1 个答案:

答案 0 :(得分:5)

不太确定你想要实现的目标,但我想你想要从一个视图向另一个视图发送消息。在这种情况下,您使用

Messenger.Send(Message.Reset);

发送消息。在收件人方面,您使用以下代码:

Messenger.Register<MessageOp>(this, (m) => {
    if (m == MessageOp.Reset) {
        // your code
    }
});

非常重要:如果您使用消息传递,请确保从Messenger中删除收件人。如果是视图模型,可以通过在视图模型上调用Cleanup来完成。在所有其他情况下使用Messenger.Unregister(收件人)。这是必要的,因为MVVM Light中的弱动作实现有一个已知问题,它自己释放收件人。

但是,如果您只想将一个按钮(或类似的东西)绑定到命令,则使用RelayCommand。

将以下定义添加到视图模型中:

public RelayCommand ResetCommand {
    get {
        return _resetCommand ?? (_resetCommand = new RelayCommand(
            () => { 
                // your execution code
            },
            () => {
                // can execute - gets called quite often!
            )
        ));
    }
}
private RelayCommand _resetCommand;

然后您可以将此命令绑定到按钮

<button Content="Reset" Command="{Binding ResetCommand}"/>

修改

要向特定收件人发送邮件,实际上有两种可能性:

  1. 发送邮件时添加令牌。
  2. 创建只有收件人订阅的自定义消息。
  3. 就个人而言,我会采用第二种方法,因为它更清晰明确 - 因此更易于维护。因此,要创建自定义消息,您可以执行以下操作:

    public class OperationMessage : GenericMessage<MessageOp> {
        public OperationMessage(MessageOp operation) : base(operation) { }
    }
    
    public class ResetMessage : OperationMessage 
    {
        public ResetMessage() : base(MessageOp.Reset) { }
    }
    

    现在你可以发送

    Messenger.Send(new ResetMessage());
    

    并收到

    Messenger.Register<ResetMessage>(this, (m) => {
        // do your resetting here
    });
    

    Messenger.Register<OperationMessage>(this, true, (m) => {
        // handle all operations here - the operation is avaiable via m.Content
    });
    

    我创建OperationMessage的原因是它更灵活,可以根据需要通用或特定地处理您的操作。