views:

120

answers:

4

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.

+2  A: 

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
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
@Matt: The Command inteface delivers a little more than an event.
AnthonyWJones
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
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
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
Schneider
+1  A: 

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
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
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
Schneider
+1  A: 

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
+2  A: 

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).

Schneider
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
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.
Schneider