Events rather than Commands in MVVM?

2019-06-18 23:56发布

问题:

It is often specified in the various tutorials of MVVM, that the goal of MVVM is not to eliminate the code-behind and that some event-handling may still be necessary in the code-behind.

What are the scenarios in which you need to write events in code-behind rather than using commands in viewmodel?

回答1:

In general, if your code pertains to UI logic, keep it in the view's XAML or code-behind. The view model is only responsible for bridging and binding data between the view and the model.

An example can be found in one of my questions, How do I make a WPF window movable by dragging the extended window frame? One of the events I use is SourceInitialized, in which I access the Window's window handle to perform some Windows API magic. But all this relates to the window, and has nothing to do with application logic beyond the window, so I restrict it all to the window's code-behind file, leaving the view model completely ignorant of it.



回答2:

In my opinion, in MVVM, when events related to UI, something like animation , you can write in the code-behind file.

All the business logic should be in view model.



回答3:

In my experience, using 3rd party controls that do not support MVVM binding will lead to writing code in code behind file. This happened even for simple usages such as selecting current item, reading currently selected item, etc. which should be fairly simple to implement in the control but has not.

A sample of this is SelectedItem property of Silverlight TreeView control, which instead of being DependencyProperty (being bindable) is a regular property so you can not bind to.

Also as @BoltClock mentioned, sometimes it seems logical to put some code in code behind which are really related to what the view does and has nothing to do with the logic "behind" the view. It is best to put these kinds of logic in the code-behind.



回答4:

You are always going to run into purists that say that there should never be ANY code in the code-behind file. I'm usually a purist, but not in this case.

If you have logic that is very specific to the view, it should go in the code-behind file. When I write complicated views that need to make large changes to the structure of the visual tree based on properties or changes in the view model, I put this code in the view. The view model should not know anything about the view, so it can't (and shouldn't) control these changes directly. Sometimes these changes can be implemented with Triggers in a Style or DataTemplate, but sometimes good old fashioned code is the best way.



回答5:

I think that there is the possibility of Custom user controls using code behind.

Let's say you create a Closable Tab Item class that inherits TabItem. You might handle that closing action using events and tie it to a DP.

This is of course generic and could be used multiple times.

So I guess code behind is acceptable when the event has to do with the UI and not the dataModel or other activity.



回答6:

One scenario I have come across is with 3'rd party controls. Some 3'rd party controls like telerik grid internally use there own custom data types to represent the grid rows etc and you need to handle the various grid events to convert those UI specific types to your custion types and then pass them to VM.



回答7:

I would say any “logic” that would needs to be different if you were porting to another desktop UI (e.g. the mac) should be in the code behind. (E.g. other platform with about the same logical UI needs)

So hooking all the events to detach when the use is “hovering” over an input field should be in the code behind, but deciding what to show in the “status line” when a user does hover should be in the view model.



回答8:

I didn't find a nice way to handle binding the selection of multiple items in listboxes and had to do it in code behind. But it's not "un-clean"