Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I put this function in View (code-behind) or in ViewModel?

Tags:

c#

mvvm

wpf

I am creating a simple WPF Application. I've a function OpenFile:

private void OpenFile(string fileName)
{
   if(!File.Exists(Helper.GetPath(fileName)))
   {
      MessageBox.Show("Error opening file");
   }
   else
   {
      //Code to handle file opening
   }
}

Ideally where should this function be present? I feel it should be in .xaml.cs because it accesses a MessageBox which comes in the View part. But it also calls my Helper, which is in the model. So I also think it can be in the ViewModel. What is the advantage of having this in the View or in the ViewModel? Can someone help me with some pointers?

Thanks.

like image 915
Sornakumar Avatar asked Mar 04 '12 08:03

Sornakumar


People also ask

How do you bind a view to a view model?

Binding using ViewModel First Approach There are two ways by which we can bind the View and View model in View First approach. The First is using the Code Behind. Suppose I have a ViewModel which is getting all the process of the system, as shown in the below code.

How do I pass a ViewModel to a code behind class?

This line of code lets us use property injection to pass the ViewModel into our code behind. The final step is to remove the OnInit () method from our @functions and place it in our code behind class. We can then delete that empty block from our View. After shuffling everything around our View now looks like this:

Should the view code-behind be kept to the view or model?

Both of these are incorrect if the view code-behind is kept to view logic. The purist approach can actually cause problems when view logic is misplaced in view models. The view models then become coupled with the view which is one of the first things MVVM is trying to avoid.

Why the ViewModel class will extend baseobservable?

The ViewModel class will extend BaseObservable because it converts the data into streams and notifies the View when the toast message property will change. The View class is responsible for updating the UI of the application. According to the changes in the toast message provided by ViewModel, the Binding Adapter would trigger the View layer.


3 Answers

One of the advantages of placing it in the view model would be testability. You could write a unit test that checks that the message box is only displayed if the file exists for example (more accurately it would be an integration test if you are hitting the file system).

However, because you are using a message box directly, your test would never complete on a build server because the machine would be waiting for input from the user whilst the message box is displayed.

Therefore, I would work against an abstraction in your view model, so that you can mock the message box during tests.

like image 114
devdigital Avatar answered Nov 11 '22 15:11

devdigital


This function must be in the ViewModel. You need to create an operation in your view for showing the error message and call this method instead of MessageBox.Show. Showing the message box needs to be done in the View.

Generally you should avoid implementing any business logic inside the View such as validating or handling a file.

like image 41
rosencreuz Avatar answered Nov 11 '22 13:11

rosencreuz


If you're using Microsoft Prism you can use the IInteractionRequest interface to have the view create the MessageBox, but actually pass back the necessary response to the view-model.

If you are not using Microsoft Prism, then look at how this part works and either simulate it or use a framework that does something similar.


Basically, that code should go on your view-model for testability, but replace the line where you explicitly call the MessageBox and use the IInteractionRequest mentioned instead.

Here is the documentation pertinent to the scenario you're looking to implement: Chapter 6: Advanced MVVM Scenarios. Look at the section stated User Interaction Patterns.

like image 44
myermian Avatar answered Nov 11 '22 13:11

myermian