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 для элемента управления, используя версию с двумя аргументами.