Здесь не хватает одного пункта: CommandTarget для данной команды может быть только объектом, который определяет CommandBinding для этой команды.
Редактировать: уточнить и исправить следующие абзацы, чтобы не оставлять вводящую в заблуждение информацию в системе.
Командная маршрутизация - это особый случай маршрутизации событий, то есть события, движущиеся вверх и вниз по логическому дереву: элементы управления, реализующие интерфейс ICommandSource, такие как InputBindings, Buttons или MenuItems, являются CommandSources. Если они поднимут команду, это приведет к запуску RoutedEvent в CommandTarget. Обычно это элемент, который имеет фокус клавиатуры. Событие перемещается вверх по логическому дереву, пока оно не достигнет корня.Все элементы с CommandBindings для команды по этому пути получают возможность обрабатывать команду, хотя обычно первый элемент, который обрабатывает команду, выигрывает и останавливает процесс маршрутизации. Это может быть даже сам CommandSource, если у него есть CommandBinding для этой команды, и это, вероятно, то, о чем ваша первая цитата. Если элемент обрабатывает событие, параметр отправителя будет элементом, который определяет CommandBinding, тогда как свойство Source RouteEventArgs события будет элементом, в котором маршрутизация пула событий, то есть CommandTarget.
Чтобы завершить путаницу, интерфейс ICommandSource определяет свойство CommandTarget. Это свойство предназначено для случаев, когда вы хотите выполнить короткую замыкание команды, и хотите, чтобы специальный элемент управления обрабатывал эту команду независимо от того, где находится фокус клавиатуры. В этом случае вы должны написать что-то вроде CommandTarget = "{Binding ElementName = MyCommandTargetControl}" на Button или MenuItem, о котором идет речь. Опять же, вы должны убедиться, что этот элемент управления имеет CommandBinding для команды, иначе команда будет постоянно отключена.
+1 Спасибо. Как я уже говорил, в случае ** Unspecified CommandTarget ** сфокусированный элемент будет считаться «CommandTarget», и механизм начнет перемещаться от него, чтобы найти ближайшее командное связующее. Следовательно, я думаю, что лучше сказать: ** «Таким образом, если у него есть CommandBinding для Command', он поднимет событие * Executed * routed (как его e.sender), и поэтому' он всегда будет обрабатывать его сам , и если это не будет, механизм продолжит поиск, пока не достигнет корня. Таким образом, это может быть включено, если на этом пути найдено другое связующее. ** Согласен со мной? – Mimi
Да, это технически более полно. Тем не менее, дело здесь в том, что настраиваемый элемент управления всегда будет его собственным CommandTarget, поскольку он всегда будет тянуть фокус клавиатуры к себе, в то время как идея не указывать CommandTarget заключается в том, что команда может обрабатываться любым элементом, который в настоящее время сфокусирован. Как я уже сказал, это ограничение можно обойти, установив FocusManager.IsFocusScope. Вероятно, нужно иметь значение между CommandTarget, элементом, который вызывает Executed RoutedEvent, и CommandHandler, элементом с CommandBinding, который обрабатывает событие. – hbarck