MVVM Light Messenger сообщение не получено от команды - PullRequest
0 голосов
/ 16 марта 2020

Я создаю приложение WPF с использованием инфраструктуры MVVM Light.

Я пытаюсь открыть окно и передать некоторую информацию, например объект, в эту вновь созданную ViewModel.

У меня есть окно WPF (MainListView / MainListViewModel), которое имеет ListBox, связанный со списком объектов:

<ListBox ItemsSource="{Binding Selected_Agent.Associated_Letter, Mode=OneWay}"
         SelectedItem="{Binding Selected_Letter, Mode=TwoWay}">
<!-- More code below -->

В MainListView У меня также есть кнопка, связанная с командой:

<Button Content="Update" Command="{Binding UpdateCommand}"/>
private ICommand _updateCommand;
public ICommand UpdateCommand
{
    get
    {
        if (_updateCommand == null)
        {
            _updateCommand = new RelayCommand(_windowService.OpenWindow<AddNewLetterView>, UpdateCommand_CanExecute());
            Messenger.Default.Send(new UpdateLetterMessage() { Letter = Selected_Letter });
        }
        return _updateCommand;
    }
}

Откроется новое окно, AddNewLetterView с использованием AddViewLetterViewModel, которое связано с ViewModelLocator.

в AddNewLetterViewModel конструкторе MVVM Light. this:

public AddNewLetterViewModel()
{
    Messenger.Default.Register<UpdateLetterMessage>(this, UpdateLetterMessageReceived);
}

Проблема в том, что это сообщение не получено. Точка останова на UpdateLetterMessageReceived никогда не срабатывает, даже если открывается вид.

Если я ставлю точку останова на моей команде, она никогда не срабатывает, и ни одна не UpdateLetterMessageReceived на AddNewLetterViewMdoel, когда кнопка нажата, даже если AddNewLetterView открыт.

Кажется, что происходит то, что UpdateCommand вызывается один раз во время создания экземпляра MainListViewModel, что означает, что Messenge отправляется до создания экземпляра AddNewLetterViewModel.

Это правильно? Если да, как я могу убедиться, что мое сообщение отправляется при вызове команды?

Если нет, что здесь происходит и как я могу этого добиться?

1 Ответ

1 голос
/ 16 марта 2020

Ваша команда обновления должна выглядеть следующим образом:

    private ICommand _updateCommand;

    public ICommand UpdateCommand
    {
        get
        {
            if (_updateCommand == null)
            {
                _updateCommand = new RelayCommand(() =>
                {
                    _windowService.OpenWindow<AddNewLetterView> ();
                    Messenger.Default.Send(new UpdateLetterMessage() {Letter = Selected_Letter});
                }, UpdateCommand_CanExecute);
            }
            return _updateCommand;
        }
    }

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

Кстати, я считаю эту структуру для команд более полезной. Это выглядит как обычный метод

public ICommand UpdateCommand => _updateCommand ?? (_updateCommand = new RelayCommand(() =>
{
    _windowService.OpenWindow<AddNewLetterView> 
    Messenger.Default.Send(new UpdateLetterMessage() {Letter = Selected_Letter});
}, UpdateCommand_CanExecute));

Чтобы сделать это более понятным, ваша функция делала это:

    private ICommand _updateCommand;

    public ICommand UpdateCommand
    {
        get
        {
            if (_updateCommand == null)
            {
                _updateCommand = new RelayCommand(DoSomething, CanDoSomething);
                Messenger.Default.Send(etc); <=====THIS SHOULD BE....
            }
            return _updateCommand;
        }
    }

public void DoSomething()
{
    _windowService etc
    <=====.....HERE
}

public bool CanDoSomething() {}

Используемая мной нотация () => {} сокращение для определения функции DoSomething

...