47

Is it possible to call a command via an event in WPF?

I have a save button that when pressed calls a command, this is pressed when you have finished editing a textbox, it also passes an object as a command parameter

 <Button Content="Save"  Command="{Binding DataContext.SaveQueueTimeCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding}" />

What I would ideally like to do is call this command and pass the object as a parameter when the textbox loses focus, rather than having to press the button, something like:

 <Button LostFocus="{Binding SaveQueueTimeCommand}" />

And still somehow pass the object as a parameter. Is there a way to acheive this without using code behind as I am using the MVVM pattern

Thanks for your time

4 Answers4

83

The simplest way to do this is using an interaction trigger:

<Grid xmlns:i="http://schemas.microsoft.com/xaml/behaviors">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SomeEvent">
            <i:InvokeCommandAction Command="{Binding Path=SomeCommand, Mode=OneWay}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Grid>
StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Trevor Tubbs
  • 2,097
  • 16
  • 18
16

You can use attached behaviors to achieve this. Marlon Grech has written the Attached Command Behaviors library to save you the trouble. Usage looks like this:

<Grid>
    <local:CommandBehaviorCollection.Behaviors>
        <local:BehaviorBinding Event="MouseRightButtonDown" Command="{Binding SomeCommand}" CommandParameter="A Command on MouseRightButtonDown"/>
    </local:CommandBehaviorCollection.Behaviors>
</Grid>
Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393
3

I'm afraid I don't think what you want to do is possible. Commands aren't delegates, so you can't write a command up to an event. I think your best option is to handle the Button.LostFocus event, and then manually execute the command from the handler.

There is nothing wrong with putting code in the code behind when using MVVM, it is just best to minimize it and keep the code to view related tasks only. I would call this code view related, so it would be find to put the code in the code behind.

Andy
  • 30,088
  • 6
  • 78
  • 89
  • 1
    Eventually, other answer clearly showed that it *is* possible (although not really directly). – SRKX Feb 04 '13 at 08:49
2
<Grid MouseRightButtonDown ="{eb:EventBinding Command=SomeCommand, CommandParameter=$e}">

</Grid>

Command

{eb:EventBinding} (Simple naming pattern to find Command)

{eb:EventBinding Command=CommandName}

CommandParameter

$e (EventAgrs) 

$this or $this.Property

string

https://github.com/JonghoL/EventBindingMarkup

Tiago S
  • 1,299
  • 23
  • 23
jongho
  • 79
  • 2