#c# #.net #wpf #cab #prism
#c# #.net #wpf #cab #prism
Вопрос:
В прошлом с Windows forms я использовал части составного блока приложения пользовательского интерфейса в сочетании с некоторой централизованной обработкой команд и правилами безопасности для достижения слабо связанного подхода MVC к привязке интерфейса к выполнению команд. Я хотел бы знать, как это сделать в WPF с помощью ICommand
или RoutedCommand
?
Мои предыдущие реализации состояли бы из следующего:
- Свяжите каждую команду со строкой в виде URI на основе REST, такого как cmd://myapp/orders/create
- Напишите пользовательский
ICommand
(не путать с WPF), который обрабатывал бы выполнение команды, у него просто былиExecute()
метод иCanExecute
свойство вместе сUndo()
и `CanUndo, если он поддерживал возможности отмены. - Объекты интерфейса, необходимые для выполнения команды, тогда будут слабо связаны
- Обработка
Click
события, которое не будет знать, какую команду выполнять, а просто передаст централизованноеCommandManager
имя команды для выполнения. - Как только
CommandManager
получит выполнение команды, он просто использует возможности «многие ко многим» в блоке приложения составного пользовательского интерфейса для вызова события command. - Перед фактическим выполнением команды диспетчер команд выполняет проверку безопасности, которая в основном заключается в том, чтобы спросить меня
SecurityManager
если вошедший в систему пользователь может выполнить командную строку, правила безопасности загружаются через XML-файл и состоят из шаблонов, таких как ‘cmd://myapp /finance /*’ - Как только событие command вызывается при получении команды, оно будет отвечать за определение состояния и контекста с помощью зависимостей, основанных на модели представления.
- Обработка
Мне нравится этот подход, потому что он прост в написании, слабо связан, а командам разрешено получать состояние интерфейса только через view-model, которые находятся через DI. Блок приложения Composite UI также упростил для меня «включить / отключить / недоступно»
Аналогичным образом я могу воспроизвести почти все, кроме ‘строкового’ представления команды, это жизненно важно, поскольку контекст безопасности, который мы написали, может заблокировать целый раздел, обрабатывая шаблоны команд, такие как cmd://myapp/finance/*
, мы также можем затем позволить пользователю определять привязки ярлыков команд и т.д.
Ключевыми требованиями для меня являются:
- Команды должны быть представлены в виде строк, это абсолютное требование.
- Должна иметь возможность указывать, что командная строка «включена», «отключена» и «Недоступна» (что означает, что она должна быть скрыта в пользовательском интерфейсе.
- Элементы интерфейса не должны знать, как обрабатывать команду или как предоставлять контекст, за это отвечают сами команды через обнаруживаемые ими объекты view-model.
- Выполнение команды должно быть централизованным, т. Е. мне нужен объект диспетчера команд, который обрабатывает вызов события для выполнения команды наряду с обслуживанием стека отмены.
РЕДАКТИРОВАТЬ: я только что подумал о том, как обеспечить привязку команды с помощью экспорта MEF для предоставления пользовательских метаданных, предоставляющих имя команды, ImportMany может затем загрузить их в my CommandManager
, теперь это просто вопрос
- Сообщать элементам интерфейса a
Command String
, которые они вызывают, и; - Разрешение изменять состояние командных строк (включено / отключено / недоступно).
ПРАВКА 2: я думал о решении, в котором my CommandManager
принимает Register(Control, String)
способ, при котором можно зарегистрировать элемент управления с помощью командной строки, диспетчер команд может затем обрабатывать включение / выключение / скрытие элементов пользовательского интерфейса по мере изменения их состояния и привязывать к ним события, это обеспечивает гораздо большую гибкость и развязку, а также позволяет настраивать пользователя (перемещение меню, конфигурации кнопок, сочетания клавиш и т.д.). Это вызывает беспокойство, хотя я не использую ни одной точки ICommand
средства, предоставляемого WPF, в конце концов, я не думаю, что это имеет значение, но я хотел бы знать, можно ли использовать средство командования, предоставляемое WPF, таким простым способом, как я определил. Другим преимуществом является то, что этот метод не зависит от WPF и может использоваться где угодно.
Ответ №1:
мне кажется, вы подгоняете себя под шаблон, который вы когда-то использовали в winforms, для использования и в wpf. обычно это не лучший подход.
но конкретно для вашей проблемы я просто хотел сказать: если вы полностью пропускаете ICommand, вы определенно теряете то, что wpf делает за кулисами. Например: метод ICommands CanExecute. WPFs commandmanager запрашивает этот метод в зависимости от пользовательского ввода в ваше приложение. В противном случае вам пришлось бы самостоятельно обрабатывать распространение изменений состояния «включено» / «отключено» / «недоступно» и реализовывать свою собственную логику для включения / выключения кнопки.
также команды можно использовать не только для событий щелчка.
и последнее: команды могут выполняться без WPF — это просто интерфейс, и он явно не привязан к wpf
Комментарии:
1. Спасибо Маркусу. Я думаю, что происходит то, что я пытаюсь найти способ сделать
ICommand
гибким, кажется, что это слишком тесно связано с реализацией команды. Наиболее важная концепция заключается в том, чтобы имена команд или ключи были представлены в виде строк, чтобы позволить модели безопасности определять, может ли команда быть выполнена из контекста безопасности. Мне кажется, что модель, предоставляемая WPF, больше настроена на действия, действующие на элементы интерфейса, а не на действия, действующие на домены.