|
Модератор
|
||||||||||||||||||||||||||||||||||||
WPF команды и MVVM. Часть 1. [WPF, Элд Хасп]18.01.2019, 19:56. Показов 55935. Ответов 92
Тема из цикла Готовые решения, примеры и рекомендации начинающим на WPF [Элд Хасп]
Для использования и создания WPF команд в Net предусмотрен интерфейс IСommand и классы RoutedCommand и RoutedUICommand. Команда - это View компонента и ей присущи чисто View-ские свойства: можно привязать её, параметр передаваемый ей, целевой элемент; она может всплывать по дереву элементов; можно обработать её по по пути всплытия. Основная проблема применения команд в MVVM, на мой взгляд, это отсутствие встроенной поддержки привязки к методам ViewModel. Дефолтно в Net обработка команд производится аналогично обработке событий элементов в CB окна. И уже в в этом обработчике можно вызвать методы ViewModel. Но тут возникает другая проблема. Как обработчику получить ViewModel? Придётся обращаться к DataContext приводить к нужному типу, походу могут возникнуть ещё другие нюансы. Самым удобным было бы привязка команд в XAML напрямую, сразу к свойствам ViewModel. Для такой привязки в большинстве случаев создают дополнительный класс реализующий интерфейс IСommand. Почти всегда его называют RelayCommand. Реализации его могут быть разные, но они очень похожи. Одна из реализаций из темы Пример реализации WPF+MVVM приложения (с учётом замечания от Lexeq)
VievModel
И окно для PlusMinusViewModel
Изменим немного ViewModel для демонстрации обработки CommandParameter.
Окно для MultiOperatorsViewModel
Изменим ViewModel так чтобы нельзя было делить на ноль.
Использование WPF команд в MVVM для простых случаев, надеюсь, объяснил подробно и понятно. Но есть более сложные применения. Допустим, есть ListBox и в нём в шаблоне Item есть кнопка. Как к ней привязать WPF команду? Для этого надо вспомнить, что WPF команда это View компонента и одним и свойств WPF команды является её всплывание по дереву. Команду надо "поймать" во включающем ListBox контейнере и обработать. Как это сделать напишу в следующей части. Архив проекта с кодами приложен. Ещё хороший пример простой для понимания предложил Lexeq в пост #10 В пост #15 финальный вариант с учётом замечаний от HF, Lexeq, Рядовой, kolorotur. Там же архив со всеми кодами из темы. В пост #64 вариант реализации RelayCommand с исправленным (при помощи proa33 и kolorotur) методом Invalidate для работы в многопоточном приложении.
12
|
||||||||||||||||||||||||||||||||||||
| 18.01.2019, 19:56 | |
|
Ответы с готовыми решениями:
92
WPF команды и MVVM. Часть 2. Всплытие команд. Реализация команды для списка элементов [WPF, Элд Хасп] Библиотека элементов для реализации WPF MVVM Решений [WPF, Элд Хасп] Обсуждение темы "Библиотека элементов для реализации WPF MVVM Решений" [WPF, Элд Хасп] |
|
Модератор
|
||
| 19.01.2019, 12:45 [ТС] | ||
|
Подобные темы планирую периодически создавать (раз-два в месяц). И если все закреплять, топик слишком разрастётся.
2
|
||
|
|
|
| 19.01.2019, 20:55 | |
|
Всё-таки считаю примеры очень сложными. Я, даже зная тему, не понял смысла и цели, пока не прочёл 4 раза сверху вниз и обратно. Если эти темы для начинающих, то я снова посоветую облегчать пример максимально возможно. Одна только разметка может быть уменьшена в 2 раза. Оставлять только то о чём идёт речь, не усложнять стилями, ресурсами, гридами и т.п.
Когда я учился, смотрел простейший пример - ввод текста в одно только поле! Ничего лишнего - текстбокс, кнопка. Всё. Во вьюмодели соответственно тоже - конструктор и создание кнопки (тоже в более лёгком виде).
5
|
|
|
|
|||||||||||
| 20.01.2019, 00:22 | |||||||||||
Сообщение было отмечено NightmareZ как решение
Решение
Да любое. Текст + кнопка.
- банальная проверка что поле текста не пустое - "посложнее" - проверка что введены только цифры Ведь цель то показать - возможности (что кнопка будет недоступная, что выполняются экшены) и как работают только нужные компоненты (чтобы когда смотришь на код, не нужно было ещё и разбиратся где именно что находится). Конечно это не MVVM, нашёл старый код, быстро скинул. Но быстро накидать ещё класс совсем не сложно. Хотя опять же - Command не связаны сильно с MVVM. Это самостоятельный механизм. Его можно использовать и так и так. Поэтому опять же, когда вы пишите везде слово MVVM, то это выглядит словно это "обязательно и только так". А то смотрите, придут знатоки с Prism и откроют глаза на другую правду.
2
|
|||||||||||
|
Модератор
|
||
| 20.01.2019, 00:28 [ТС] | ||
|
Я это сразу уточнил в начале темы. Я Вас не тороплю, подумайте. Нужен простой пример применения WPF команд в MVVM. Обязательно нужно выделить ViewModel и сделать привязку команд к методам ViewModel.
0
|
||
|
|
||
| 20.01.2019, 00:38 | ||
|
Пока напишите мне пожалуйста в чём разница команды и команды в mvvm? Если кроме место расположения кода есть что-то ещё, то было бы интересно узнать.
0
|
||
|
1524 / 914 / 329
Регистрация: 17.05.2015
Сообщений: 3,438
|
|
| 20.01.2019, 01:29 | |
|
HF, на программном уровне разницы нет. Разница в восприятии.
Лично мне было бы неясно, зачем это городить, если можно в клике все прописать. Сам начал использовать этот паттерн, только когда начал путаться в большом проекте. Но из примера автора и правда можно было бы убрать стили и всякие IReadOnlyCollection...
0
|
|
|
1151 / 743 / 483
Регистрация: 21.01.2014
Сообщений: 1,903
|
|||||||||||||||||||||||||||||||
| 20.01.2019, 02:19 | |||||||||||||||||||||||||||||||
|
Элд Хасп, мне тоже кажется, что все слишком переусложнено, особенно для новичков. OnPropertyChangedClass монстр на все случаи жизни. Модель и вьюмодель слились воедино, хотя вы пишете что главное тут показать команды в рамках MVVM. Логика, построенная на сравнении строк тоже попахивает(что-то из разряда if(button.Text == "Ok") в формах). И код в посте отличается от кода в проекте:
Кликните здесь для просмотра всего текста
Command
Model
ViewModel
View
Добавлено через 23 минуты Fix
4
|
|||||||||||||||||||||||||||||||
|
Модератор
|
||||
| 20.01.2019, 02:42 [ТС] | ||||
|
0
|
||||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
|||||||
| 26.01.2019, 09:52 | |||||||
|
Идея понятна: если надо заставить кишки WPF вызвать CanExecute, делаем вызов CommandManager.InvalidateRequerySuggeste d, который через сквозное привязывание обновляет забинденный элемент. Проблема в том, что это вызовет обновления на всех забинденных командах, что может быть довольно накладно, если их в интерфейсе много (список с кнопочками?). Более правильный вариант:
3
|
|||||||
|
Модератор
|
||
| 26.01.2019, 15:47 [ТС] | ||
|
О проблемах вызывающих его использование читал, но как их решить не задумывался - не было надобности. Ваш пример обязательно учту. Спасибо!
0
|
||
|
Модератор
|
|||||||||||||||||||||
| 26.01.2019, 16:07 [ТС] | |||||||||||||||||||||
|
Привожу финальный вариант с учётом замечаний HF, Lexeq, Рядовой, kolorotur. В варианте явно выделена модель и убраны стили из окна.
Класс RelayCommand
WpfCommands v2.zip - архив проекта без Решения. Проект надо подключить к имеющемуся Решению. WpfCommandsSln.7z - архив Решения с проектом.
2
|
|||||||||||||||||||||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
|||||||||||
| 26.01.2019, 17:51 | |||||||||||
|
Раз уж пошла такая пьянка, приведу свой вариант реализации команды для обертки асинхронных операций:
AsyncCommand.cs
Блокирует повторный запуск на время выполнения и предоставляет свойство IsExecuting с уведомлением об изменении для биндинга и всяких свистелок вроде отображения прогресса. Поддерживает отмену, так же опционально можно задавать таймаут, но реализующий класс должен следить за передаваемым токеном. В случае отмены вручную или по таймауту вызывается виртуальный метод ExecutionCancelled для дополнительной обработки наследующимся классом. Дефолтная реализация пустая. Наследующийся от нее AsyncRelayCommand для обертки асинхронного метода: AsyncRelayCommand.cs
3
|
|||||||||||
|
|
|||||||
| 26.01.2019, 18:13 | |||||||
|
Но блин.. сразу в глаза бросается В двух местах. Значит можно вынести в метод.
0
|
|||||||
|
|
||
| 26.01.2019, 19:44 | ||
|
Добавлено через 23 минуты Плюс OnCalculate повторяет логику IsCanExecuteCalculate. Получается что метод CanExecute и не нужен. Он снова проверится.
0
|
||
|
Модератор
|
|||||
| 26.01.2019, 20:15 [ТС] | |||||
|
Напишу почему я так сделал. Сразу оговорюсь - не претендую на правильность, напротив интересно иное мнение и критика. Методы VM и Model различаются функционально. В Model они оперируют с данными, а в VM приводят данные к нужному типу и если приведение удалось то обращаются к методам модели. Теоретически parameter может быть привязан к чему угодно (в том числе и по ошибке). В зависимости от его значения дальнейшие действия VM могут быть различны. В данном случае parameter проверяется только на тип. Но, допустим, в модели не единый метод для всех значений parameter , тогда VM будет ещё анализировать и его значение и в зависимости от результата обращаться к разным методам Модели.Передавать же напрямую parameter в Модель без предварительной обработки, на мой взгляд, не корректно. Для обработки parameter нужны знания о View, а Модель ими не обладаетView же ничего о OperatorsEnum не знает. Ей это знание не нужно. Добавлено через 7 минут CanExecute это метод класса RelayCommand - он здесь причём? Что-то не дошло до меня о чём Вы здесь пишите.
0
|
|||||
| 26.01.2019, 20:15 | |
|
Помогаю со студенческими работами здесь
20
Создание приложения "Штатное Расписание" в паттерне MVVM [WPF, Элд Хасп] WPF конвертеры [Элд Хасп] WPF vs WinForms (для начинающих) [Элд Хасп] Готовые решения, примеры и рекомендации начинающим на WPF [Элд Хасп]
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта
Симптом:
После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
|
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов.
. . .
|
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
|
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
|
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут.
В век Веб все очень привыкли к дизайну Single-Page-Application .
Быстренько разберем подход "на фреймах".
Мы делаем одну. . .
|