#1,091 – Using a CommandTarget to Change the Source of a Routed Command

The source of a routed command is the element that is invoking the command.  The sender parameter in the Executed or CanExecute handlers is the object that owns the event handler.  Setting the Command parameter of a Button to a particular command and then binding the command to some code in the CommandBindings for a main Window, the button is the source and the window is the sender.

When setting the Command property, you can also set the CommandTarget property, indicating a different element that should be treated as the source of the routed command.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Commands" Width="320" Height="220">

    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Find"
                        CanExecute="Find_CanExecute"
                        Executed="Find_Executed"/>
    </Window.CommandBindings>

    <StackPanel>
        <TextBox Name="txtSomeText"
                 Width="140" Height="25" Margin="10"/>
        <Button Content="Find"
                Command="ApplicationCommands.Find"
                CommandTarget="{Binding ElementName=txtSomeText}"
                Margin="10" Padding="10,3"
                HorizontalAlignment="Center" />
    </StackPanel>
</Window>

The Find command now appears to originate from the TextBox.  We can see this in the event handler for the Executed event.

1091-001

 

#1,090 – Sender vs. Source in CommandBinding Event Handlers

When handling a command’s Executed or CanExecute events, you can check the ExecutedRoutedEventArgs.Source or CanExecuteRoutedEventArgs.Source properties to get at the control that is the originator of the event.  But the event handler also includes a sender parameter that in many cases also points to the originator of the event.

The difference is:

  • The Source property refers to the originator of the event
  • The sender parameter refers to the object that owns the event handler

In the example below, clicking on the Button initiates a Paste command, which is bound to code using the parent Window’s CommandBindings property.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Commands" Width="320" Height="220">

    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Paste"
                        CanExecute="Paste_CanExecute"
                        Executed="Paste_Executed"/>
    </Window.CommandBindings>

    <StackPanel>
        <Button Content="Paste"
                Command="ApplicationCommands.Paste"
                Margin="10" Padding="10,3"
                HorizontalAlignment="Center" />
    </StackPanel>
</Window>

The Button is the Source of the routed command and the main Window is the sender.

1090-001

#622 – The Source of a Keyboard Event

The source of a keyboard event is the control that had keyboard focus when the key was pressed, referenced by the KeyEventArgs.Source property in a keyboard event handler.  You can consider the source as–the control where the keyboard event is taking place.

The source can be different from the sender of the event, which is the control to which the event handler was attached.

For example, if you have a TextBox contained in a StackPanel and you press a key while the TextBox has focus, the TextBox is the source of the event.  If you then attach a handler for one of the keyboard events to the StackPanel, the StackPanel is the sender of the event.

    <StackPanel KeyUp="StackPanel_KeyUp">
        <TextBox Text="I'm a TextBox" HorizontalAlignment="Center"
                 KeyUp="TextBox_KeyUp"/>
    </StackPanel>

#603 – Sender, Source and OriginalSource Example

Event handlers for routed events in WPF will have access to three different user interface elements within the handler:

  • sender – the element that raised the event
  • e.Source – element where the event originated
  • e.OriginalSource – original low-level element where the event originated (e.g. sub-element in a control)

Suppose that we have the following logical tree:

    <StackPanel Orientation="Vertical" UIElement.MouseMove="StackPanel_MouseMove">
        <Button Content="Move Mouse Over Me" MouseMove="Button_MouseMove"/>
    </StackPanel>

When we move the mouse over the text on the Button, the MouseMove event fires, first on the Button itself and then on the StackPanel (because MouseMove is a bubbling event).  Here are the values of the three fields when you handled each of these events:

  • MouseMove fires on the Button
    • senderButton
    • SourceButton
    • OriginalSource = TextBlock (the TextBlock that is a child control of the Button)
  • MouseMove fires on the StackPanel
    • senderStackPanel
    • Source = Button
    • OriginalSource = TextBlock