10

There is a lot of effort in the Silverlight community to keep a XAML's code behind file as free of code as possible. What is the real motivation behind this?

For example, what is the advantage of using a command instead of an event handler? If I have

<Button x:Name="SaveButton" Content="Save" Click="SaveButton_Click" />

...

private void SaveButton_Click(object sender, RoutedEventArgs e) {
    _myViewModel.SaveChanges();
}

Then why is this prefered?

<Button x:Name="SaveButton" Content="Save" Command="{Binding SaveCommand}" />

Where obviously the SaveCommand in my view model is effectively going to invoke SaveChanges().

This can lead to situations where the view is 100% XAML, even instantiating the view model in XAML, and the connections between the view and view model are completely done through binding. Sure it's clean, but what else is it? Flexible? Why? the view still needs to work with the proper ViewModel, so if the connection between the two exists and is implicit, why not make it more explicit? It also has the disadvantage of losing compile time support. If I hook my button up to an event handler that doesn't exist, the compiler will tell me. It won't if I bind to a non-existent command.

Matt Greer
  • 60,826
  • 17
  • 123
  • 123
  • 1
    I am inclined to agree with you on this, that if you don't have the kind of application where commands are broadly useful, then I don't really see what the extra typing buys you. As you say, it doesn't affect the testability of the viewmodel one way or another. Some people hold the view that once you start to have ANY code-behind code, you won't be able to stop yourself sneaking logic into it which should be in the viewmodel. – Will Dean Jul 27 '10 at 15:52
  • The preference is due to testability not xaml/codebehind markup. This question would be really interesting if your code example had the two approaches to testing these alternatives. ie your test for ViewModel.SaveChanges() and a ICommand based test. – itchi Jul 28 '10 at 03:47

4 Answers4

5

There is a lot of effort in the Silverlight community to keep a XAML's code behind file as free of code as possible. What is the real motivation behind this?

I would say that people who want the code behind "as free of code as possible" are those who have jumped on the MVVM bandwagon without really getting the point. (Either that or you have misinterpreted their point).

The point is not to keep the code-behind free of code, but to make sure that the View is only responsible for visual presentation. That fact that many visual aspects can be defined declaratively means there is less code in the code-behind, but it does not mean you should hesitate to write code-behind where you feel it is necessary and does not transgress outside the view's responsibilities.

what is the advantage of using a command instead of an event handler?

A Command offers at least two capabilities that an event handler doesn't. Some WPF controls are aware of the CanExecute property of the Command, so for example a button can be disabled when the command is not available to execute. Also the designer and binding framework are Command aware.

If you just want to call a method on a button press there is no great advantage to using Commands instead of just calling the method from an event handler. So don't be afraid to use this approach. (A third approach, which favours designer over programmer, is to use the CallMethodAction from Blend 4).

Jack Ukleja
  • 13,061
  • 11
  • 72
  • 113
  • While I generally agree with you, I think there's a value in keeping the xaml free of code just to keep the separation as clean as possible. While sometimes rules should be broken, when you do so repeatedly it's easy to get in the habit of breaking them unnecessarily. – kyoryu Jul 31 '10 at 06:41
  • Having no code in "XAML" has NOTHING to do with SoC (what I presume you mean by "clean separation"). If the code is concerned with the responsibilities of the View then you are not violating the SoC principle. – Jack Ukleja Jul 31 '10 at 06:58
3

It makes unit testing and / or TDD easier. By using MVVM and commanding, I can essentially build my view model and commands TDD style and have most of the view logic tested without actually having the XAML view at all.

Daniel Auger
  • 12,535
  • 5
  • 52
  • 73
  • 1
    How? Are you unit testing your views? Nothing I suggest has a real impact on the viewmodel, making it equally testable in both scenarios. – Matt Greer Jul 27 '10 at 15:47
  • @Matt: The Command inteface delivers a little more than an event. – AnthonyWJones Jul 27 '10 at 15:49
  • Updated my answer... Once the XAML view becomes about presentation only, you can can unit test all of the presentation behavior since it's on the viewmodel and in the commands. The visual correctness of the views are tested by humans. – Daniel Auger Jul 27 '10 at 15:54
  • Ok, that helps. So essentially you are including testing the commands themselves. That does make sense, especially if your commands aren't trivial. – Matt Greer Jul 27 '10 at 15:56
  • 2
    If the answer really is "it makes testing easier" then every single good practice and architectural principle exists to "make testing easier". I think not. Easier testing is a *side effect* of the fundamental principle at work here - Separation of Concerns – Jack Ukleja Jul 31 '10 at 06:46
1

There are probably many arguments you might hear for it but pragmatically there is only one, testability. A ViewModel delivers little unless you build a unit test for it, which in turn implies that you would need to create the ViewModel in such a way that you can unit test it, using techniques such as dependency injection, IoC, blah, blah, etc, etc.

The result is that unit tests can cover a larger part of your applications code than you could achieve had you kept the UI code more integrated.

I'm not necessarily recommending it, to do it properly takes considerable design effort and forethought. Hence the costs in building such an approach are quite high, however, the savings of the increased quality may well offset those costs.

AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
  • Sure, and I do all of that. I have full unit tests for all of my view models. I feel like I'm missing something fundamental here. How the view calls back into the viewmodel doesn't seem to make much difference in testing. It seemed to me like one advantage to this approach is using IoC to allow you to inject dummy data and potentially design your views in Blend in a way that closer matches their real use. – Matt Greer Jul 27 '10 at 15:51
  • Matt you are not missing anything. Using an event handler vs Command does NOT affect testability. Everybody has jumped on the MVVM bandwagon and they always use Commands in the examples even when there is often no advantage for many scenarios – Jack Ukleja Jul 31 '10 at 07:04
1

The main advantage I see with the command is when you have the dual requirement of executing an action and validating that the action can execute (i.e. context). In other words, if you are simply linking the click with a straight method call, I agree, I see no advantage either. If the click should be conditioned, however, and the button disabled based on context, then the binding facilitates this through the CanExecute property.

This way, instead of having to worry about controls in the view (i.e. having the logic that says "find this control, and set it to disabled because we can't execute it right now) we can create a command and simply ensure that can execute returns false. This is testable independent of the view and once you do bind it, the binding itself takes care of managing the control's enabled property.

Jeremy Likness
  • 7,531
  • 1
  • 23
  • 25