2015-05-08 5 views
3

Вот мой код:Исполнен получает не вызывается после PreviewExecuted

var commandBinding = new CommandBinding(ApplicationCommand.New); 
commandBinding.PreviewExecuted += OnPreviewExecuted; 
commandBinding.Executed += OnExecuted; 
CommandBindings.Add(commandBinding); 

void OnPreviewExecuted(object sender, ExecutedRoutedEventArgs e) { 
    e.Handled = false; 
} 

void OnExecuted(object sender, ExecutedRoutedEventArgs e) { 
    DoSomething(); 
} 

MSDN говорит: «... Если событие предварительного просмотра не обрабатывается, казненного событие возникает в цель команды.»

Это верно работает для события PreviewCanExecute. Но в этом случае Executed-Event не будет вызываться при прослушивании PreviewExecuted-Event.

Я не нашел ничего вокруг этой темы, поэтому я хочу спросить, является ли поведение намеченным или просто неправильным.

+0

Может быть, код другого места получил событие (через туннелирование) и обработал его. – Kryptos

+0

В принципе нет. Такое поведение происходит даже в свежем минималистском образце проекта с помощью всего одной кнопки и кода выше. – Stephan

ответ

5

Кажется, что не имеет значения, что вы установили e.Handled.

Вот код, который решает, какие события поднять (ExecuteImpl в RoutedCommand.cs):

ExecutedRoutedEventArgs args = new ExecutedRoutedEventArgs(this, parameter); 
args.RoutedEvent = CommandManager.PreviewExecutedEvent; 

if (targetUIElement != null) 
{ 
    targetUIElement.RaiseEvent(args, userInitiated); 
} 
else 
{ 
    ... 
} 

if (!args.Handled) 
{ 
    args.RoutedEvent = CommandManager.ExecutedEvent; 
    if (targetUIElement != null) 
    { 
     targetUIElement.RaiseEvent(args, userInitiated); 
    } 
    ... 
} 

Так на самом деле, если e.Handled является false после события предварительного просмотра, то Executed события должно быть поднято. Но это никогда не ложно после PreviewExecuted обработчик вызывается (CommandBindings.cs, OnExecuted):

PreviewExecuted(sender, e); 
e.Handled = true; 

Он просто устанавливает e.Handled к истинным после вызова обработчика предварительного просмотра ...

Почему это так, я не имеют ни малейшего представления о. PreviewCanExecute работает так же, но только устанавливает e.Handled в true, если для параметра e.CanExecute установлено значение true - если вы делаете это в своем обработчике предварительного просмотра, обработчик CanExecute не будет вызываться независимо от e.Handled.

Мое предположение, что «Если событие предварительного просмотра не обрабатывается» является неудачной формулировкой «Если событие предварительного не имеет зарегистрированный обработчика».

+0

Вы полностью правы. Здесь (http://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Input/Command/CommandBinding.cs,213) является ссылкой. Я попрошу некоторых сотрудников Microsoft по поводу «почему» – Stephan

+0

См. Также [этот более ранний ответ] (http://stackoverflow.com/a/4877259/3513925), который подтверждает, что 'e.Handled' не имеет эффекта и маршрутизация немедленно останавливается как только будет запущен первый обработчик (который будет 'Preview *'). @Stephan, любые разъяснения почему? – Zeus