RoutedCommands, которые используют туннелирование вместо всплытия

У меня есть пользовательский элемент управления (MyControl), который предоставляет пользовательскую команду. Я хочу, чтобы родитель Window мог вызывать эту команду, и все MyControls должны были на нее реагировать.

Я добавил команду в коллекцию CommandBindings MyControl, которая также обеспечивает обратный вызов CanExecute, который всегда возвращает true.

Моя проблема в том, что пункт меню, который вызывает эту команду, никогда не включается. Я предполагаю, что это потому, что меню находится над MyControls в визуальном дереве, но, честно говоря, я немного не понимаю, как именно работает область RoutedUICommand.

Может кто-нибудь объяснить, что я делаю неправильно, или если это вообще возможно?


person GazTheDestroyer    schedule 04.10.2012    source источник


Ответы (2)


Да, дело в том, что CommandBinding для вашей пользовательской команды находится ниже вашего пункта меню в визуальном дереве. Из msdn

Когда вызывается метод CanExecute для RoutedCommand, событие PreviewCanExecute вызывается для цели команды. Если событие не обрабатывается, возникает событие CanExecute. Если цель команды имеет CommandBinding для команды, вызывается обработчик CanExecute для этого CommandBinding. Если цель команды не имеет CommandBinding для команды, событие CanExecute выводит всплывающее окно вверх по дереву элементов в поисках элемента, который имеет CommandBinding, связанный с командой.

Очень хорошая статья о командах в по этой ссылке.

В любом случае вы можете использовать CommandTarget команду из вашего пункта меню, например

<MenuItem Header="Click me"  Command="local:CommandClass.MyCustomCommand" CommandTarget="{Binding ElementName=myCustomCtrl}" />

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

person Klaus78    schedule 04.10.2012
comment
К сожалению, мне нужно, чтобы ответили ВСЕ экземпляры MyControl, а не только один, поэтому CommandTarget для меня бесполезен. Отметили свой ответ, потому что подтвердили, что это невозможно. - person GazTheDestroyer; 08.10.2012

Я предполагаю, что команды - это неправильное значение здесь.

Команды используются для связывания различных источников запуска команд с одним обработчиком команд. Таким образом, команда запускается из разных элементов управления, меню... но вызывается один и тот же обработчик команды.

События как бы наоборот. Один источник может запускать несколько обработчиков событий.

В вашем особом случае я бы предпочел событие, и элементы управления под вашим деревом пользовательского интерфейса будут слушать события туннелирования или всплывающие события.

person Rat Baron    schedule 31.01.2013