|
Использование команд (ICommand) вне View
|
|||
---|---|---|---|
#18+
Вопрос концептуальный. Интересует мнение со стороны. Моё мнение: Я отталкиваюсь от этого: https://docs.microsoft.com/ru-ru/dotnet/api/system.windows.input?view=netframework-4.8 System.Windows.Input Namespace Предоставляет типы для поддержки системы ввода Windows Presentation Foundation (WPF). Сюда входят классы абстрагирования устройств для устройств мыши, клавиатуры и пера, часто используемые классы диспетчера ввода, поддержка для команд и пользовательских команд, а также различные служебные классы. Если под командой понимать только реализацию ICommand , то не должно быть (использование ICommand в Модели). ICommand находится в пространстве System.Windows.Input. Это пространство специфично только для WPF. А Модель, в принципе не знает, с какого типа View будет её использовать. Может Формы или Консоль? А у них нет пространства System.Windows.Input. Тоже самое относится и к ViewModel. Хотя паттерн MVVM появился как способ реализации инструментов предоставленных WPF, это не означает, что его можно использовать только в WPF. И у VM (в идеале) не должно быть информации о View, даже о её типе. Используя же ICommand мы даём такую информацию VM и тем самым жёстко её завязываем на WPF View. Но в реале, делая MVVM приложение мы всегда подразумеваем, что в нём будет WPF View. Исключения, возможно есть, но мне они ни когда не встречались. И если Модель ещё как-то потенциально делается унифицировано, без жёсткой завязки на WPF (допустим для многоплатформенного приложения, или разные View на одну Модель для более широкого охвата аудитории), то VM всегда делается жёстко под WPF. По этой причине проникновение ICommand в VM проблем не создаёт. Но в ИДЕАЛЕ такого быть в MVVM не должно. Если же под командой понимать контейнер объединяющий исполнительный метод, разрешающий метод и событие извещающее об изменении состояния разрешающего метода, то в том или ином виде это довольно часто используется в Модели. Пример. Есть долгий асинхронный метод. Если обратиться к нему во время исполнения - будет исключение. Поэтому к нему есть разрешающий метод позволяющий определить возможность обращения к исполнительному методу. А так как о состоянии Модели VM может узнать только из событий, то по началу и окончании работы исполнительному метод должен вызвать соответствующее событие. То есть идея ICommand сама по себе имеет довольно широкое применение. Проблема этого интерфейса его размещение в пространстве для WPF. Размести MS его в пространстве System.ComponentModel , там же где находится INotifyPropertyChanged , то никаких ограничений на использовании ICommand в Модели не было бы. INPC можно же использовать где угодно (без фанатизма, конечно). Так же было бы и с ICommand . Но с таким пониманием, возникает необходимость в создании кастомного аналогичного интерфейса. Что тоже "не есть хорошо". ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2020, 13:18 |
|
Использование команд (ICommand) вне View
|
|||
---|---|---|---|
#18+
при чем тут пространство имен? тип ICommand находится в сборке System, на этом всё. к WPF он имеет очень посредственное отношение, так как этот интерфейс относится к шаблону поведения "Команда", который может применяется много где еще, хоть в WF, хоть в Backend сервисах. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2020, 13:45 |
|
Использование команд (ICommand) вне View
|
|||
---|---|---|---|
#18+
Roman Mejtes, спасибо за внимание к вопросу. Можете дополнительно высказаться по реализации интерфейса? На мой взгляд, реализации для WPF и для Модели должны быть разными. Для WPF событие событие CanExecuteChanged надо создавать в Диспетчере. Так же для типизированной команды (RelayCommand<T>) приведение из object желательно (или необходимо) делать через TypeConverter ( https://stackoverflow.com/questions/63248032/wpf-eventhandler-for-textbox-textchanged-in-xaml-or-code-behind/63268987?noredirect=1#comment112007521_63268987). Реализация же для Модели во всех этих "прибамбасах" не нуждается. Её надо делать максимально лёгкой и быстрой. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.08.2020, 14:38 |
|
Использование команд (ICommand) вне View
|
|||
---|---|---|---|
#18+
Eld Hasp, не понимаю, что тут можно высказывать. Поведенческий шаблон "Команда", совсем не подразумевает использование каких то конкретных интерфейсов, это лишь подход к решению какой либо задачи. Стоит её применять или нет, можно сказать только по факту. Например, для построения интерфейса в котором необходимо реализовать Undo\Redo, шаблон "Команда" вполне себе отлично подходит, но если просто взять интерфейс ICommand становится очевидно, что он недостаточен, можно создать команду которая будет выполнять как Undo, так и Redo, а CommandManager и CommandScope будут управлять процессом отмены или возврата операций и областью их применения. А интерфейс ICommand будет выполнять роль адаптера для вызова операции Redo, ведь нам нужно вызывать как то наши команды из View, по возможности, очевидным путём. Если говорить о каких то моделях, то есть вещах не связанных с пользователем, то, например, у вас есть объект, над которым вы хотите выполнять ряд каких то операций, но их порядок и список заранее не определен и зависит от внешних факторов или внутреннего состояния, более того сам клиент вызывающий команды может ничего не знать о том, что они вообще выполняют. Обычной командой называют, такой тип операции над объектом который определяется внешним фактором, обычно вводом пользователя, при этом команда абстрагирована от контекста выполнения, то есть клиент (к примеру, кнопка) вызывающий команду ничего о ней не знает (кроме ссылки). ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2020, 10:44 |
|
|
Start [/forum/topic.php?fid=21&fpage=1&tid=1440265]: |
0ms |
get settings: |
21ms |
get forum list: |
21ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
85ms |
get topic data: |
16ms |
get forum data: |
3ms |
get page messages: |
164ms |
get tp. blocked users: |
2ms |
others: | 16ms |
total: | 334ms |
0 / 0 |