WPF две команды обработчики, одна команда

Я получаю от стороннего контроля. Это реализует ApplicationCommands.SelectAll. Однако поведение, которое я хочу, немного отличается. нет виртуального метода, который я мог бы переопределить, и когда я регистрирую обработчик класса, вот так

     CommandManager.RegisterClassCommandBinding(typeof(MyDerivedControl), new CommandBinding(ApplicationCommands.SelectAll, new ExecutedRoutedEventHandler(OnExecutedSelectAll), new CanExecuteRoutedEventHandler(OnCanExecuteSelectAll)));

Мои методы не вызывают. Сторонний контроль, от которого я получаю, маркировка

e.Handled=true;

в его обработчиках команд (я знаю эту причину, я видел источник, но я не могу изменить его)

Что я могу сделать?

1 ответ

Решение

У вас есть три варианта:

1) Вы можете зарегистрировать свой CommandBinding для обработки событий предварительного просмотра вместо или в дополнение к обычным событиям:

CommandBinding cb = new CommandBinding(ApplicationCommands.SelectAll);
cb.PreviewCanExecute += OnCanExecuteSelectAll;
cb.PreviewExecuted += OnExecutedSelectAll;

но будьте осторожны - при регистрации обработчиков через CommandBinding, если вы зарегистрировали PreviewExecuted, обработчик Executed никогда не запустится, даже если вы явно установите для e.Handled значение false. Это работает, как и ожидалось, для пары событий PreviewCanExecute/CanExecute. Это способ реализации класса CommandBinding.
Поэтому используйте PreviewExecuted, только если вы не хотите запускать обработчик команд базового класса.

2) В качестве альтернативы вы можете зарегистрировать ваши обработчики команд через CommandManager напрямую:

CommandManager.AddPreviewCanExecuteHandler(this, OnCanExecuteSelectAll);
CommandManager.AddPreviewExecutedHandler(this, OnExecutedSelectAll);

Это не обработчик класса, поэтому вам нужно будет делать это для каждого экземпляра. Затем в вашем обработчике вам нужно будет проверить погоду, эта команда вас интересует (в аргументах событий есть ссылка на команду). Примечание: вам все равно придется зарегистрировать CommandBinding, но если вы собираетесь добавлять обработчики только непосредственно в CommandManager - вам не нужно регистрировать какие-либо обработчики в этой привязке команд.

3) Или вы можете немного взломать (не совсем взломать):

this.AddHandler(CommandManager.CanExecuteEvent, new CanExecuteRoutedEventHandler(OnCanExecuteSelectAll), true);
this.AddHandler(CommandManager.ExecutedEvent, new ExecutedRoutedEventHandler(OnExecutedSelectAll), true);

таким образом вы регистрируете обработчики событий команд, чтобы они выполнялись, даже если они уже были обработаны.
Как и в предыдущем пункте, вам нужно зарегистрировать привязку команды для запуска событий CommandManager.
Это почти то же самое, что и в пункте 2 выше, но когда вы вызываете CommandManager.Add[одно из четырех событий]Handler - менеджер команд вызывает AddHandler для элемента управления, используя версию с двумя аргументами.

Другие вопросы по тегам