События, а не команды в MVVM?

в различных учебниках MVVM часто указывается, что цель MVVM не заключается в устранении кода и что некоторая обработка событий все еще может быть необходима в коде.

каковы сценарии, в которых вам нужно писать события в коде, а не использовать команды в viewmodel?

8 ответов


В общем случае, если ваш код относится к логике пользовательского интерфейса, сохраните его в XAML или коде представления. Модель представления отвечает только за объединение и привязку данных между представлением и моделью.

пример можно найти в одном из моих вопросов, как сделать окно WPF подвижным, перетащив расширенную оконную рамку? одним из событий, которые я использую, является SourceInitialized, в котором я получаю доступ к Windowдескриптор окна для выполнения некоторой магии Windows API. Но все это относится к окно, и не имеет ничего общего с логикой приложения за окном, поэтому я ограничиваю все это файлом кода за окном, оставляя модель представления полностью в неведении об этом.


на мой взгляд, в MVVM, когда события, связанные с UI, что-то вроде анимации , вы можете написать в файле кода.

все бизнес-логика должна быть в модели представления.


по моему опыту, использование сторонних элементов управления, которые не поддерживают привязку MVVM, приведет к написанию кода в коде за файлом. Это произошло даже для простых обычаев, таких как выбор текущего элемента, чтение выбранного элемента и т. д. что должно быть довольно просто реализовать в элементе управления, но не имеет.

образец этого свойства SelectedItem элемента управления Silverlight TreeView, который вместо DependencyProperty (будучи bindable) является регулярным свойством, поэтому вы можете не привязываться.

также, как упоминалось в @BoltClock, иногда кажется логичным поместить некоторый код в код, за которым действительно связаны с тем, что делает представление, и не имеет ничего общего с логикой "позади" представления. Лучше всего поместить эти виды логики в код.


вы всегда будете сталкиваться с пуристами, которые говорят, что никогда не должно быть никакого кода в файле кода. Обычно я пурист, но не в этом случае.

Если у вас есть логика, которая очень специфична для представления,она должна идти в файле кода. Когда я пишу сложные представления, которые должны внести большие изменения в структуру визуального дерева на основе свойств или изменений в модели представления, я помещаю этот код в представление. Модель представления не должна ничего знать о представление, поэтому оно не может (и не должно) напрямую контролировать эти изменения. Иногда эти изменения могут быть реализованы с помощью триггеров в стиле или DataTemplate, но иногда хороший старомодный код является лучшим способом.


Я думаю, что есть возможность пользовательских элементов управления, используя код.

предположим, вы создаете закрываемый класс элементов табуляции, который наследует TabItem. Вы можете обработать это действие закрытия с помощью событий и связать его с DP.

Это конечно универсальный и может использоваться несколько раз.

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


один сценарий, с которым я столкнулся, - это 3-й партийный контроль. Некоторые 3-е партийные элементы управления, такие как Telerik grid, внутренне используют собственные типы данных для представления строк сетки и т. д., И вам нужно обрабатывать различные события сетки, чтобы преобразовать эти типы пользовательского интерфейса в типы custion, а затем передать их в VM.


Я бы сказал, что любая "логика", которая должна быть другой, если вы переносите на другой пользовательский интерфейс рабочего стола (например, mac), должна быть в коде позади. (Например. другая платформа с примерно такими же логическими потребностями пользовательского интерфейса)

таким образом, закрепление всех событий для отсоединения, когда использование "зависает" над полем ввода, должно быть в коде позади, но решение о том, что показывать в "строке состояния", когда пользователь делает наведение, должно быть в модели представления.


Я не нашел хороший способ справиться с обязательного выделения нескольких элементов в списках и должен был сделать это в коде. Но это не "не-чистый"