3

I know this has been done to death, but most answers are along the lines of "yeah, you can use eventhandlers in place of commands if you like". This still doesn't solve the problem of whether writing complicated commands is warranted vs just wiring up eventhandlers in code behind to call testable methods in your view model.

I don't like commands because they produce a lot of boilerplate code and don't give me any benefit over normal methods, plus some of them (such as drag & drop) are a pain to implement.

What's wrong with writing:

codebehind:

private void Button_Click(object sender, RoutedEventArgs e)
{
    viewModel.LoadData();
}

viewmodel:

public void LoadData()
{
   //....
}

This is equally testable (if not more) as any command is. IMO, as long as UI specific stuff isn't leaking into your business logic, there's really no need to waste time on complicated patterns like that. Thoughts?

  • As an aside, I know of at least one framework that has some clever infrastructure that would let you bind to LoadData() and optionally a CanLoadData() methods. This isn't a plug for the framework (which is caliburn/caliburn.micro) and I don't recommend it for beginners. BUT I wouldn't be shocked to see other framworks, perhaps even MS follow suit eventually, and it is a plug for keeping your logic in your view model, with one extra benefit being the potential to migrate to such a framework and have your cake and eat some too. Suck it up and go with the commands at first though, I'd say. HTH – Berryl Feb 17 '11 at 03:40

3 Answers3

5

What's wrong with writing

Nothing - for the most part.

There is nothing wrong with using code behind, if you are careful to keep the business logic out of the code behind file. This is delegating this directly to the ViewModel, which is reasonable.

That being said, there are a couple of potential downfalls here in terms of long term maintainability:

  1. By doing this, you're coupling the View to the ViewModel more tightly. While this is a reasonable thing to do (the View, in reality, always knows about the ViewModel), it does prevent potential reuse of View components in some scenarios, as using an ICommand allows you to have the same View be used with potentially different ViewModels. (This is rare in practice, however.)
  2. This starts a slippery slope - by adding "any" code into code behind, you're opening up the potential that another developer will add "just one more line" in there. Over time, this can lead to a mess.
  3. It's adding code into another place that has to be maintained. Now you'll have to maintain the ViewModel .cs file, your .xaml file, and the code behind file.
  4. You're hard-wiring this logic into a Button. If you decide to change controls, use a gesture, etc., you'll have to remember to rework this logic.
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
3

I was in your boat at first, I even asked basically the same question here. But I came around and came to really like commands.

Some commands really are complex enough in and of themselves to warrant testing. They are just as testable as anything else on your viewmodel.

ICommand also includes CanExecute and CanExecuteChanged, which enables your view to intelligently enable/disable itself pretty much for free. This is fantastic in complex views.

Commands make it easier to change your view around, most controls have a Command property you can bind to, and simply moving the binding around is easier than mucking with event handlers. This is especially true if you have designers working on the XAML.

You can pretty much write the entire logic of the view without the view even existing. It leads to a nice flow of build the meat all at once, then throw the interface on top all at once.

Keeping your code in one place leads to longer term maintainability.

Community
  • 1
  • 1
Matt Greer
  • 60,826
  • 17
  • 123
  • 123
  • There's the added bonus of the IsActive property to completely remove the control if required. That makes handling roles so much easier. – R4cOOn Feb 17 '11 at 13:55
0

To me a very important argument against events is forcing the UI Designer to write code to be able to test a View. And worse: every time he redesigns the View he has to rewire the events.

Commands and the behaviors in Blend make render this process obsolete and much easier.

Another problem might arise when actually using the event arguments when writing the event handler. When you want to switch to another control or another event you might have become very dependent on the event arguments making it hard to switch because the other control/event does not support the same event arguments.

Emond
  • 50,210
  • 11
  • 84
  • 115