When to use events over commands in WPF?
Asked Answered
E

2

30

Hi i have recently looked into WPF and started learning about Events and Commands. I typically use Commands on Button clicks which causes a method to Run in my "view model".

Is it possible to make the Button react to any other events like the MouseOver event through the use of commnds? Or would WPF Events be used in this case?

If WPF Events are to be used, then should the event handler implementation just call a method in the View Model to keep concerns sperate?

Express answered 23/5, 2011 at 14:32 Comment(1)
If you haven't already, I highly suggest Laurent Bungion's MIX and Techday video streams including the excellent MIX11 deep dive MVVM broadcast which covers a lot of these MVVM edge cases.Farmhand
F
13

This is a fair question, and one that is a common, yet "solved" (debatably) problem within the MVVM architecture realm. If you are using an MVVM framework, you are likely to find something similar to the EventToCommand Behavior, here is the sample from the MVVM Light Toolkit.

In short, this allows you to map an event to a command binding like so:

<Rectangle Fill="White"
       Stroke="Black"
       Width="200"
       Height="100">
<i:Interaction.Triggers>
    <i:EventTrigger EventName="MouseEnter">
        <cmd:EventToCommand Command="{Binding TestCommand,
                                      Mode=OneWay}"
           CommandParameter="{Binding Text,
                              ElementName=MyTextBox,
                              Mode=OneWay}"
           MustToggleIsEnabledValue="True" />
    </i:EventTrigger>
</i:Interaction.Triggers>
</Rectangle>

Update:

There are two other "reasonable" solutions to this problem:

One uses the now considered legacy "AttachedCommandBehavior" extension found here.

The other is a little bit irritating, but workable.

  1. Capture a command via en event purely in the view.
  2. Query the control's DataSource Step
  3. Grab a string binding target identifier that denotes your command (perhaps using a const string on the view)
  4. Invoke your command on the view model via reflection and pass in the command arguments.

This looks gross but I'm fairly certain is actually a bit faster than just using traditional command bindings. In order to be sure I'd need to see the IL, and I don't think that it matters in this case.

/Update

I want to note however that this is not always an ideal situation. I've discovered that more often than not, I'm using EventToCommand to cover a design issue. Please consider the following:

  • Use events and code behind to handle User-Interface related behaviors.
  • Consider creating custom controls that have command bindings if appropriate, especially if you find yourself using commands to encapsulate event driven bevahior to set bound data that is then reflected in the view. (i.e. setting a transparency value based on proximity to a control or something similar)
  • EventToCommand should most likely be used to handle "Command-like" events only (double clicking etc) not reactive events (mouse-over). However there is nothing preventing this. Implement as you see fit.

Most importantly perhaps is that you remember that you are the developer. Guidelines in themselves do not solve problems, but consideration of guidelines may make the solution to a problem apparent.

Farmhand answered 23/5, 2011 at 14:55 Comment(0)
D
6

You might want to take a look at this post:

WPF Commands vs Events Advantages/Disadvantages

which talks about the different usages of events and commands.

As far as commands for other events, you should take a look at something like EventToCommand as part of the MVVMLight Toolkit, which allows you to attach any event to a command in your viewmodel. Quite useful, especially if you're already using MVVM Light (which I highly recommend).

Delainedelainey answered 23/5, 2011 at 14:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.