Отправить команду через MVVMLight - PullRequest
1 голос
/ 16 сентября 2011

Я использую MVVMLight и прохожу небольшую кривую обучения, чтобы попытаться понять, как работает связь. Я понимаю, как Свойства работают вместе с привязкой 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 Ответ

5 голосов
/ 17 сентября 2011

Не совсем уверен, что вы пытаетесь достичь, но я думаю, вы хотите отправить сообщение из одного представления в другое.В этом случае вы используете

Messenger.Send(Message.Reset);

для отправки сообщения.На стороне получателя вы используете следующий код:

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

Очень важно: если вы используете обмен сообщениями, обязательно удалите получателя из Messenger.В случае модели представления это можно сделать, вызвав функцию очистки для модели представления.Во всех остальных случаях используйте 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. Создать пользовательскийсообщение, на которое подписывается только получатель.

Лично я бы пошел на второй подход, так как он более понятный и явный - и, следовательно, более понятный.Итак, для создания собственного сообщения вы можете сделать следующее:

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, заключается в том, что он более гибок и позволяет вам обрабатывать ваши операции в целом или по мере необходимости.

...