Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF MVVM Code Behind

Tags:

c#

.net

mvvm

wpf

I try to avoid code behind in views, within my WPF MVVM project.

However I have some things that are very specific to the view. For example when a control gets focus I want the full text to be highlighted (even if a user clicks into the text box).

Here I have a choice to handle this in the view model (which would then need to know about the view, which I want to avoid).

I also have some other code like that does things to the UI when the user presses up down left or right on the keyboard (and they only make changes to the view, not the model or viewmodel) and again I'm thinking the best place for these is in the code behind of the view.

So I'm asking if the code only affects the view (e.g. things like cursor movement, selecting all text in a text box etc..., and not the model or view model, is it okay to put it in code behind, rather than elsewhere.

Wondering what is best practise here, or if anyone else has a better suggestion where to put this code.

like image 762
DermFrench Avatar asked Jan 02 '14 12:01

DermFrench


People also ask

What is code-behind in MVVM?

If you do access the viewmodel from code-behind in the view, you should try and do it via an interface. This means your viewmodel is injected or given to the view as an interface. (Note that the binding subsystem doesn't know or care about the interface, it will continue to bind in its normal way.

What is code-behind WPF?

Code-behind is a term used to describe the code that is joined with markup-defined objects, when a XAML page is markup-compiled. This topic describes requirements for code-behind as well as an alternative inline code mechanism for code in XAML. This topic contains the following sections: Prerequisites.


2 Answers

So I'm asking if the code only affects the view (e.g. things like cursor movement, selecting all text in a text box etc..., and not the model or view model, is it okay to put it in code behind, rather than elsewhere.

Not only it is OK, but it is strongly encouraged. MVVM is not here for you to write thousands of ugly lines of code in ViewModels, it's here to make the code testable and to introduce a separation of concerns.

If it's purely related to the view (your "focus" example is a perfect example), then just write it in the code behind.

like image 152
ken2k Avatar answered Sep 28 '22 22:09

ken2k


If the behavior is UI related only, then you should not put it in the ViewModel. The highlighting example you gave is a good example of such a case. Having said that, I would suggest you avoid repeating your code by (for example) creating a custom control that highlights the text when it has the focus. This way, you can reuse the control in as many views as you can, your views stay free of codebehind, and if you optimize your control, the optimizations happen across the board.

EDIT:

In light of Ravi's answer, Behaviors are also a way to introduce UI related logic while leaving the View free of codebehind. However, if you are finding yourself repeatedly declaring the same controls with the same behaviors, in my opinion it is better to create a control that incorporates the behavior.

That being said, if said UI logic is going to appear only once in one view, you may consider putting it in codebehind. Although it is quite rare to know in advance that you are not going to need that logic elsewhere.

EDIT:

I think @ken2k 's use of strong encouragement refers to not putting it in the ViewModel, which I also advocate. UI logic should be implemented in the View, as he says. Now, there are a few ways of doing that. One of these is coding it directly in your codebehind, which can lead to repetitious code and maintenance issues. Also, if you employ unit testing, it could put you in a difficult spot. The second is coding such logic into behaviors, which is a good way to encapsulate UI code. You can then unit test the behavior to make sure it works OK. However, you can find (as I did, in many projects) that you have started to pepper every TextBox in your XAML's with behavior tags. If that starts to happen, I would (and have) create a 'HighlightedTextBox' control and use that in my XAML. In summary, my suggestion does not contradict ken2k's, but is a pointer in the direction of resolving some issues you may have when placing logic for your View.

like image 21
Boluc Papuccuoglu Avatar answered Sep 29 '22 00:09

Boluc Papuccuoglu