3

Here's my code:

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 says:"...If the preview event is not handled, the Executed event is raised on command target."

This does work correctly for the PreviewCanExecute event. But in this case the Executed-Event will not get called when a PreviewExecuted-Event is listening.

I did not find anything around this topic so I want to ask, whether the behavior is intended or just incorrect.

Mark C.
  • 6,332
  • 4
  • 35
  • 71
Stephan
  • 53
  • 6
  • Could be that code some other place got the event (through tunneling) and handled it. – Kryptos May 08 '15 at 12:51
  • Basically no. This behavior occurs even in a fresh minimalistic sample project with just a single button and the code above. – Stephan May 08 '15 at 13:00

1 Answers1

5

It seems it doesn't matter what you set e.Handled to.

Here is the code that decides which events to raise (ExecuteImpl in 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);
    }
    ...
}

So indeed, if e.Handled is false after the preview event, the Executed event should be raised. But it is never false after a PreviewExecuted handler is invoked (CommandBindings.cs, OnExecuted):

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

It simply sets e.Handled to true after invoking the preview handler...

Why this is so, I have no idea. PreviewCanExecute works the same way, but it only sets e.Handled to true if e.CanExecute is set to true - if you do that in your preview handler, the CanExecute handler won't be called regardless of e.Handled.

My assumption is that "If the preview event is not handled" is an unfortunate wording of "If the preview event does not have a registered handler".

ASh
  • 34,632
  • 9
  • 60
  • 82
svinja
  • 5,495
  • 5
  • 25
  • 43
  • You are cpmpletely right. Here (http://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Input/Command/CommandBinding.cs,213) is the reference. I will ask some microsoft employees for the "why" – Stephan May 08 '15 at 13:23
  • See also [this earlier answer](http://stackoverflow.com/a/4877259/3513925), which confirms that `e.Handled` has no effect and routing immediately stops as soon as the first handler (which will be `Preview*`) is executed. @Stephan, any clarifications why? – Zeus Apr 06 '16 at 00:19