Страницы

Поиск по вопросам

пятница, 20 декабря 2019 г.

Общая схема обработки событий в паттерне MVVM

#c_sharp #wpf #mvvm


Хочу выяснить схему обработки событий при использовании паттерна MVVM.


Как я понимаю, ни одного обработчика события в коде быть не должно, так как они возможны
только в code behind, а его использовать плохо, так?
Вся обработка событий происходит через команды. Для этого надо писать простенький
класс вроде этого, в который вставлять свои делегаты, создавать свойства-команды и
привязывать их к элементам?

class RelayCommand : ICommand
{
    private Action _executeDelegate;
    public RelayCommand(Action executeDelegate)
    {
        _executeDelegate = executeDelegate;
    }
    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _executeDelegate(parameter);
    }
}

А как обрабатывать разные события от одного и того же элемента? Как я понял, команда
выполняется для какого-то одного "основного" события? 
Можно ли получить аргументы события (те же аргументы, что и у обычного обработчика)?
Есть ли какие-то более красиве методы? Например, через привязку команд? Только как
эти привязки добвлять в окно, если ViewModel не имеет ссылки на него?

    


Ответы

Ответ 1



1, 2. На мой вкус, не совсем так. Правильное место для обработчиков событий — UI-специфические задания. Например, вы хотите измерить какой-нибудь контрол, и если его ширина менее 10% контейнера, то скрыть его полностью. Для этого вы подписываетесь на событие изменения размера. Это специфическая задача уровня презентации, которая к VM не имеет никакого отношения. Использовать для неё команду — неправильно, вам не нужна тут слабая связанность. 3. Обычно элемент не должен иметь в своём интерфейсе две команды. Например, для кнопки единственное событие, которое может быть интересно VM-уровню — это нажатие самой кнопки. Изменение размера кнопки для VM интереса не представляет. Соответственно, кнопка (Button) имеет лишь одну команду. Если вы пишете кастомный контрол, который реально может произвести несколько различных интересным для VM-уровня событий, определите в нём несколько команд. 4. Не могу ничего прибавить к точке зрения @ixSci: для этого есть CommandParameter. 5. Есть возможность ещё уменьшить связность, воспользовавшись предопределёнными командами. Пример: пункт меню может объявить своей командой предопределённую команду ApplicationCommands.Save (), и привязать имплементацию команды Save где-то в другом месте кода (см. CommandBinding).

Ответ 2



Это так, но любая максима есть глупость. Поэтому надо смотреть по обстоятельствам. В любом случае это то, к чему нужно стремиться. Да, либо же использовать готовые MVVM библиотеки, типа MVVM Light. В уже упомянутой мною MVVM Light есть такая штука как EventToCommand, пример можно посмотреть тут У команды есть CommandParameter, туда Вы можете передавать всё, что угодно:

Комментариев нет:

Отправить комментарий