What is in ViewModel in MVVM [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have spent long time searching about MVVM in WPF. I understand why to use it. This is clear for me.
What I don't is, what is in ViewModel itself. I know it is the connection between the View and the Model. Also, I know (at least, what most of programmers suggest) that implement the INotifyPropertyChanged. Adding to this, the Commands.
Let say, that I have this Model (Code First with EF 6):
public class City
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CityId { get; set; }
[DataType("VarChar"), MaxLength(25), Required]
public string CityName { get; set; }
}
My Questions are:
1- In many examples I've seen, they recreate the same fields again in VM. What is the purpose, is it enough to have the whole object (City in my example). How about if there are many fields!.
2- To be able, to use it in my View (CRUD), how is the CityVm() will be in my example?.
I appreciate any help.

The view model in the MVVM pattern encapsulates the presentation logic and data for the view. It has no direct reference to the view or any knowledge about the view's specific implementation or type. The view model implements properties and commands to which the view can data bind and notifies the view of any state changes through change notification events. The properties and commands that the view model provides define the functionality to be offered by the UI, but the view determines how that functionality is to be rendered.
The view model is responsible for coordinating the view's interaction with any model classes that are required. Typically, there is a one-to many-relationship between the view model and the model classes. The view model may choose to expose model classes directly to the view so that controls in the view can data bind directly to them. In this case, the model classes will need to be designed to support data binding and the relevant change notification events.
The view model may convert or manipulate model data so that it can be easily consumed by the view. The view model may define additional properties to specifically support the view; these properties would not normally be part of (or cannot be added to) the model. For example, the view model may combine the value of two fields to make it easier for the view to present, or it may calculate the number of characters remaining for input for fields with a maximum length. The view model may also implement data validation logic to ensure data consistency.
The view model may also define logical states the view can use to provide visual changes in the UI. The view may define layout or styling changes that reflect the state of the view model. For example, the view model may define a state that indicates that data is being submitted asynchronously to a web service. The view can display an animation during this state to provide visual feedback to the user.
Typically, the view model will define commands or actions that can be represented in the UI and that the user can invoke. A common example is when the view model provides a Submit command that allows the user submit data to a web service or to a data repository. The view may choose to represent that command with a button so that the user can click the button to submit the data. Typically, when the command becomes unavailable, its associated UI representation becomes disabled. Commands provide a way to encapsulate user actions and to cleanly separate them from their visual representation in the UI.
To summarize, the view model has the following key characteristics:
The view model is a non-visual class and does not derive from any WPF base class. It encapsulates the presentation logic required to support a use case or user task in the application. The view model is testable independently of the view and the model.
The view model typically does not directly reference the view. It implements properties and commands to which the view can data bind. It notifies the view of any state changes via change notification events via the INotifyPropertyChanged and INotifyCollectionChanged interfaces.
The view model coordinates the view's interaction with the model. It may convert or manipulate data so that it can be easily consumed by the view and may implement additional properties that may not be present on the model. It may also implement data validation via the IDataErrorInfo or INotifyDataErrorInfo interfaces.
The view model may define logical states that the view can represent visually to the user.

This is a pretty broad topic based a lot on opinion. The MVVM model isn't a set-in-stone thing, and there's lots of different ways of implementing it.
The ViewModel, in my opinion, has two main purposes:
1) To expose the Model to the View. There's two ways of doing this. Having your Model wrap your CRUD object and manage NotifyPropertyChange. In this case, it's common for your ViewModel to just expose the Model to the View and not do much else with it, the View binding directly to the Model, or via simple pass-through properties.
The other common scenario is just to have your model as a CRUD. In this case, the ViewModel manages the NotifyPropertyChange notifications and manages model updates, etc.
2) To manage Presentation logic and data. There's lots of things that you need to bind to and store that have no place in the Model. The Model is the data. It's most likely loaded from a database. Yet the View needs to track other properties. An example: say your city object is displayed in a list, and you want to show or hide it with a button. The logic for hiding it, and the boolean for it being hidden doesn't belong in the View, and has nothing to do with the base data in the Model, so it sits in the ViewModel.
Similarly, maybe you have a CityPopulation property. In your view you want to highlight cities that are larger than 1,000,000 population in red. Your View Model has the a property:
bool LargeCity
{
return CityPopulation<1000000;
}
And you render the label with a style trigger.
Another example, a ViewModel containing a Brush property to bind to, which I think is probably a common but bad practice. slugster also comments below that visual elements should not be present in the ViewModel.
Brush HighlightBrush
{
get
{
if (CityPopulation<1000000)
{
return Brushes.Red;
}
else
{
return Brushes.Black;
}
}

1- In many examples I've seen, they recreate the same fields again in
VM. What is the purpose, is it enough to have the whole object (City
in my example). How about if there are many fields!.
Since the view model is the responsible of implementing view's logic and it performs actions against the model, there're some cases where some properties wouldn't be necessarily part of the model, but they're just there to serve view's requirements.
For example, let's say your model has a Name and Surname, and you want to show a concatenation of both properties in your view. You may be able to implement this using binding expressions or implementing a property in your view model:
public string FullName => $"{Model.Name} {Model.Surname}";
2- To be able, to use it in my View (CRUD), how is the CityVm() will
be in my example?.
This question has no specific answer. But you'll need a Model property at least to store a given City.

Related

Managing Cancelable Partial Updates using MVVM

I’m new to MVVM and am trying to establish good practices as I convert a large non-Model-View WinForms project. Here’s an example of a solution I’ve implemented. I’m wondering if there is a better pattern for solving this class of problem.
MyModel has ten properties. MyView exposes two of them for users to update. MyViewModel handles the usual stuff in between.
Other models depend on MyModel’s properties, so I only want to change MyModel when values are committed to. MyView has OK and Cancel buttons, so instead of having MyViewModel directly update MyModel when the user interacts with MyView, I’ve created another layer: MyTempModel. MyTempModel contains two properties which correspond to the two from MyModel.
So inside MyModel, prompting code looks something like this:
var tempModel = new TempModel{Prop1=Prop1,Prop2=Prop2};
bool? response = new MyView().ShowDialog();
if (response.HasValue && response.Value)
{
Prop1 = tempModel.Prop1
Prop2 = tempModel.Prop2
}
Thus if the user clicks ‘Cancel’, MyModel’s properties are not changed.
Note: Not shown here is that I set a reference to MyTempModel in MyViewModel once to establish that wiring. MyViewModel subscribes to property changed events in MyTempModel and MyView uses databinding to connect to MyViewModel.
model - > view data flow summary:
MyModel sets property in MyTempModel, which fires an event. MyViewModel’s evenhandler picks up the change and sets a dependency property, causing MyView to update.
view -> model data flow summary:
Changes to MyView result in dependency property in MyViewModel to change. This property’s setter pushes the value to MyTempModel. When user clicks Ok then MyModel copies values from MyTempModel.
I'm particularly interested in the role of the ViewModel. I have in mind that keeping dialogs "humble" is a good thing, and maybe that is spilling over into making ViewModels humble. So comments on what kind of functionality you put into your view models vs your domain models would be especially interesting.
I appreciate any and all design wisdom for this pattern. I'll gladly update this info if anyone needs clarification.
I don't think the use of a proxy class is a bad thing. I'm a little concerned about this: 'MyModel sets property in MyTempModel, which fires an event. MyViewModel’s evenhandler picks up the change and sets a dependency property, causing MyView to update.' I think that renders your Model classes a little less universal and obscures that functionality from the ViewModel. I would just use the ViewModel to mediate the swap in/out of the proxy, rather than having the Models do it. I also think that using a proxy opens up use of DataTemplates for that type which could make the UI work easier.
An alternative to the direction given by Alex is to make the viewmodel a representation of what is in both client and server side.
E.g., the number shown is always what the user entered and the background of the number indicates that this number has been confirmed or not (pending)by the server. The viewmodel could use two different properties to contain these values and a status property to indicate the fact the property has been synchronized.
This way the viewmodel captures all the user needs to know. All the view needs to do is bind to the correct properties for display and editing.

Putting ui attributes on domain model

My web application currently has a domain model and a view model. Domain model is almost a representation of my database. So when I insert data into a table, i'm inserting my domain model object. My view model handles how I want to display my ui. So if i have a property on view model that has a drop down list, i give it a custom display attribute drop down list with an enum saying what kind of values to load ([DropDownList(Enums.Product)]. My view model also has display labels and calls specific editor templates for the different properties using UIHint. I feel like creating a view model is becoming repetitive. I'm wondering if there's any harm in just putting display attributes (uihint, display(name="blah")) right on my domain model so i can skip the view model unless specifically need it for something. The only other solution is to actually wite out the html so that i'm using Html.Editor("SomeProperty", Model.SomeProperty) instead of Html.EditorFor(x => x.SomeProperty). Any thoughts?

A ViewModel shared across multiples Views

I need some help about MVVM pattern.
I created a ViewModel that expose data and commands to be displayed in a listview in a View named A.
This ViewModel is also used in a view named B. In this view, i just need to expose some properties and no commands but i had to create 2 more properties.
Is it better to create a more specific ViewModel for View B even if it concerns the same object?
I would suggest composition, have two view models which both have a property containing a view model that holds the common properties. The two view models should then only have their specific other properties and commands.
Difficult to answer. But i can tell you what we do for our application. We have one viewmodel, which is more or less view independant, it just functions as a wrapper for our business data and contains all the stuff that is used in almost all parts where this model is shown. Now for the view part, we have very specific viewmodels. Like a ProjectTreeViewModel or a SearchResultViewmodel, with the corresponding Item viewmodels for both of them. The Item viewmodel doesn't need to implement all the logic again, it just needs to agregate the general model view model.
To give a better analogy:
If you have a File, Drive and Folder model. You would create a FileViewModel, DriveViewModel and FolderViewModel. But only one ExplorerItemViewModel. This only needs to provide a property to expose the underlying view model. The rest is depending on your data templates.

Dynamically Adding Different Views Using MVP

First off let me say this is my first attempt into trying MVP. I am going for the Passive View approach as I want to completely decouple the Views from the Model.
I have read up on MVP by reading the following articles among others
Derek Greer
http://aspiringcraftsman.com/2007/08/25/interactive-application-architecture/
Todd Snyder
http://blogs.infragistics.com/blogs/todd_snyder/archive/2007/10/17/mvc-or-mvp-pattern-whats-the-difference.aspx
My application is going to have 4 Views that are custom controls in which each implement a different interface to interact with the Presenter. Now this is not a problem for 3 of the views as the controls are static and never change.
My problem comes along where on the 4th View I need to change the control/View that is displayed based on events triggered from View 1.
So for example lets say View 1 is a list of people who can be from either an employee or a customer. Now depending on who is selected you can modify different parameters depending on the type of person selected. The problem is that View 4 needs to dynamically change the editing control based on what is selected. Keep in mind not only the properties will be different but how they are edited as well. Also each editing control is going to fire different events for property changes.
So how does my Presenter know how to manage interaction with the Model, when depending on whether an employee or customer is selected there is a different editor that implements a different View interface?
I hope that was clear. Any help is greatly appreciated. I have searched all over and all examples show a concrete relationship between the View and Presenter whereas mine needs to be extremely flexible.
My goal here is to keep the editing controls on the 4th View so flexible that I could for example add editing controls/Views for aliens or dogs or whatever else I might add to View1 to be selected.
Thanks
You can create a top-level presenter that listens for selection events and changes the editing control by instantiating different MVP triads based on what is selected. Typically in MVP your presenters manage all the construction/dependencies.
I personally don't like having a 'Master Presenter' per se. I do build composite presenters: e.g. View can contain one of several views, so I build a Presenter for the master view, which sends commands (messages, events, whatever) to a specific child presenter (I don't expose any View outside it's owning Presenter).
Don't over-complicate things ...use a different View for each responsibility. Views are cheap.

HiddenInput(DisplayValue) needs to be in the CREATE View false but in the LIST View true

I have an enum view model property which I want to hide in the CREATE View but show in the LIST/Index View. The enum is Open,Failed,Succeeded.
For the CREATE View the editor/control should not be visible.
For the LIST View the editor/control should be a selectable combobox
Can this be done somehow with the HiddenInput attribute?
If this can not be done then I want at least to make it visible in both views, but disabled/another control (label instead of combobox).
I am using asp.net mvc 4.0
Actually you should be using different view models. Remember: the first word of view model is view meaning that you define a view model per view. So you will have a CreateViewModel that will be used for the Create view without the enum property in question and a ListViewModel with the enum property that will be used in the Index view.
When doing code reviews I see many developers trying to reuse the same models over different views and ending up with some horrible logic because those models simply are not adapted for those views. They try to hide, they try to write ifs and stuff to perform validation, usually end up in a maintenance nightmare.

Categories

Resources