4
votes

I would like to get some opinions on when/if it is ok to put code in codebehind. I've only been at this for less than a year now. So, I still consider myself very "green". I come from a Delphi background. So, the learning curve has been tremendous to say the least – learning WPF, XAML, C#, Unity, Prism, MEF, .NET, MVVM, etc… Fun but very challenging.

When I first started less than a year ago, the idea in the office was no code in codebehind if at all possible and no view specific code in the VM.. So, I have racked my brain many times to determine how to push literally everything into the VM and keep what I think is view specific code out of the VM only to come up short almost every time. I’m to the point now, I’m beginning to think codebehind is not always bad or “wrong”. I have recently been trying to clean up some of our views by attempting push any codebehind into the VM which led me to find a neat factory class at http://blog.functionalfun.net/2008/09/hooking-up-commands-to-events-in-wpf.html. This allows you to bind routed events to ICommands in the VM. It works like a charm and I was able to significantly reduce some of our codebehind with it. However, after doing so, I’m now questioning my decision to do so. My approach followed the philosophy that codebehind was bad/wrong unless absolutely required. Now that I have had a little time to think about it, I’m not so sure the refactor was the best idea.

The following is an example of a view I refactored. We have a new account view where the user enters an SSN and must rekey the SSN before the new account can be created. The view has a label that displays text to tell the user if the SSN and rekey SSN do not match and the OK button is not enabled until they both match. Once the SSN and rekey SSN match, the label disappears (yes I know… I hate that but I’m just the developer) and the OK button is enabled. So, the hiding/showing of the label and enable/disable of the OK button is triggered from the TextChanged events in the SSN and rekey SSN text boxes. Initially I had logic in codebehind to compare the two textbox values and set viewmodel properties appropriately to update the visible property of the label and the OK button’s enabled property (yes their properties are bound in XAML). After finding this new factory class, I used it to push all of the code into the viewmodel and the view works just like it did before just without codebehind. After successfully refactoring the view, I am now second guessing the decision to refactor.

My concern is, what if we want to have a different view in the future and the new view doesn’t want to handle mismatched SSN’s in that fashion. Maybe the new view would allow the user to type in mismatching SSNs and then display an error message when the OK button is clicked. Should the new view have to accept the extra overhead of code in the viewmodel executing for every keypress in the text boxes? That just doesn’t sound right to me. I’m starting to think the viewmodel should contain what is required to support what the view needs but not do everything for the view. The view should be able to make decisions based on something in the viewmodel but not depend on the VM to hold its hand – right?

1
In the future, you should format your question in a way that is easy for the reader to figure out what you're trying to ask.Nathan

1 Answers

5
votes

The XAML and matching .cs file make up the view. Because of that there's nothing wrong with putting code in the codebehind as long as it's for the view itself.

There is certainly nothing "wrong" with codebehind.

Here's how I'd handle your SSN example:

  1. Bind both SSN fields to properties on the view model
  2. Bind the OK button to a command in the view model (I'm a big fan of the Delegate Command concept)
  3. The command should implement the CanExecute portion and only return true when both SSNs match.

It doesn't seem that the SSN matching is a view concern, it's a business practice. It belongs in the view model. What would be in the view is how your application shows that the SSNs do or don't match.