considering a situation where only the user updates the ViewModels/Models through the UI, there's no external access to the data displayed.
Why does the ViewModel should implement INotifyPropertyChanged in this case?
It makes only sense to me to have a ViewModel implementing it when there's external access to the data so that the UI has to be notified somehow about an external-initiated property-change and you set up Mode=TwoWay/Mode=OneWay.
Most of the sample MVVM implementations I saw never subscribe anything the the ViewModels PropertyChangedEventHandler, but still implement it, just because it has to be done, since it's mvvm.
If the user changes one item in the view it may affect multiple items in the viewmodel, or it may affect the state of one item in the viewmodel that in turn affects the presentation of multiple items in the view.
I would have to turn the question on its head and ask, given the above statements, why would you not implement INotifyPropertyChanged? It's hardly a massive overhead.
Related
In learning Xamarin.Forms/UWP/WPF tutorials always tout MVVM as the design pattern of choice and I've followed suite, but I've never understood why. To contrast, in asp.net MVC the templated framework is used to great effect, Controllers deliver models to the view (HTML of some sort).
But in the Xamarin.Forms/UWP/WPF and others, we create a completely new class, ignore the code-behind file that cannot be removed and relegate it to telling our view where to look when binding data.
The only reason I could think of that makes MVVM better is if we could supply logic where different VM's could be 'injected' into the same view, maybe that would justify it.Though I have no idea how to do that.
Otherwise, how is creating a view model class better than using the code behind file? Is it really worse separation of concerns just because the view and code behind have the same name and are instantiated together?
MVVM pattern is much cleaner than using code-behind.
Separation of concerns
Imagine you have a view and a code-behind implemented. Now the business comes with a request to completely change the way the controls are presented - replacing them with new controls, changing layout and so on. Chances are, you will be forced to rewrite a lot of code just to satisfy the requirement, because the code-behind is directly tied to the view.
Now in case you have MVVM in place, you can easily swap the View part of the equation for any view which utilizes data binding to the right properties in a View model. You could easily present a single View model in several different ways - like creating multiple different views for different user roles while the view model stays exactly the same, you just choose what to display and how.
What view model actually creates is a middle layer between data and their presentation and makes it possible to more easily transform the data the view uses and change the presentation without affecting the view model if the interface is kept intact.
Data binding
Also if you are meaning purely code-behind without data-binding, the advantages of MVVM become even clearer. When you have a data-bound property that updates after user input in a TwoWay manner, for example if you have a form the user has to fill out, you don't have to remember to fetch the latest "changes" from the control using Text property, you know the latest version is already there in the data-bound property. In addition, you can add validation in the property setter, you can update other properties in the setter as well to orchestrate data handling in a much more abstract way than with code-behind approach, where you are tied to events and having to remember where the data come from and which specific controls and which specific properties you have to update. Imagine you display a given text in multiple places - with data binding you just set a single property and rely on {Binding} to display the text in all bound controls. With code-behind only, you need to remember which concrete controls display the text and when you add a new control, you have to update the code-behind appropriately, which is far less convenient.
Cross platform development
Another example would be having to develop a cross-platform application with native UI using MvvmCross. Here you can decide that some views or some functionality will not be available for certain OS or that you want to just implement it later. This is entirely possible - you just don't provide the UI for that functionality and the view model can stay the same.
View state
Finally - having all view state in code-behind means that when you navigate away, you must store the state somehow and restore it when navigating back because a new page is created. With MVVM you may decide to keep the view models of the navigation stack in memory and when navigating back just set the DataContext of the page to the existing view model instance to get back just in the same state as you left off.
Overall I see MVVM as a great pattern to improve flexibility of your codebase and it makes your solution more future-proof and resilient to changes.
Almost every MVVM example I've come across has both the Model and ViewModel implementing INotifyPropertyChanged.
Other sources (ones which focus on domain modeling) seem to suggest that Models should be incredibly plain (something to do with separation of concerns?) with essentially no references to anything. Unfortunately, those sources don't use MVVM.
I'm trying to reconcile the two.
-I'm relatively new to programming and completely new to design patterns and the like so please try to go easy on me.
Edit: Let me rephrase my question. Given that the answer to the above seems to be "sometimes one and sometimes the other," WHEN should you do one and and when should you do the other. Also, how would each be implemented?
(That isn't answered in the other post. It just has them arguing with each other).
Models have to implement INotifyPropertyChanged to inform the view model that they have changed. If the model doesn't implement INotifyPropertyChanged (or another equivalent interface), then the view model is stuck using polling or other similarly inefficient methods to detect changes in the model state.
This MSDN page may be useful reading to further understand the roles of the various components that make up the MVVM pattern.
I have no idea if this is a best practice, but I have my ViewModel set up so that it is the only active entity. The Model is only directly changed when created by reading from a database (and then loaded into a ViewModel), or before saving to database (extracting from ViewModel, modifying Model properties that only matter to the database, like foreign keys).
If for some reason you desire being able to have multiple ViewModels connected to the same Model or have a need to change a Model from under a ViewModel, then you'd have a good reason to implement INotifyPropertyChanged on the Model.
I'm a relative amateur, so take what I say with a grain of salt. But this is what I've been gathering, and enforcing this separation has, I think, made my code cleaner and easier to understand and debug. So for my own projects, I'm going to try avoiding implementing INotifyPropertyChanged on my Models if I can avoid it.
I'm creating a simple network application that communicates with one or more services, so I planned to use some queues (for outgoing messages and incoming ones), a table, a list containing the status for each active connection, etc.: in other words, these are the data structures needed to ensure the functioning of the application itself.
This application must also be equipped with a graphical interface that shows part of the internal functioning of the application itself: for example, the filling status of queues, the status (detected speed, etc.) of the connections, etc.. According to the Model-View-ViewModel pattern, the model consists of the data to be displayed in the GUI: in this application, the aforementioned data structures represent the model. In other words, the Model implements the business logic of the application.
The ViewModel should implement INotifyPropertyChanged interface in order to notify the View that a change is occurred, but how does the Model to communicate with the ViewModel? After reading this article, I realize that the INotifyPropertyChanged interface is implemented by the model. This answer explains a little more, but it confuses me a bit:
INotifyPropertyChanged - Should go into ViewModel and Model (if needed)
Why, if needed?
When should I implement this interface?
When should I not implement it?
Moreover, the Dictionary does not implement the INotifyPropertyChanged interface: if I use it, should I wrap it with a class which implements this interface?
Finally, the model should be read-only, meaning that the user does not be able to change the contents of internal data structures using the GUI. How to accomplish this?
how does the Model to communicate with the ViewModel
Any way you want it to. In most of the apps we write, the view model makes calls to the business logic layer (the model). However, if you have a need for the view model to be notified immediately (events) of changes to the model, you could implement INotifyPropertyChanged on your model. Or you could simply have the view model subscribe to events on the model.
Moreover, the Dictionary does not implement the INotifyPropertyChanged interface: if I use it, should I wrap it with a class which implements this interface?
You only need to have the view model implement INotifyPropertyChanged. Properties within the view model (dictionary) will simply invoke NotifyPropertyChanged (or whatever your implementation looks like).
Finally, the model should be read-only, meaning that the user does not be able to change the contents of internal data structures using the GUI. How to accomplish this?
Don't provide the user the functionality to let them change the data. Make the binding one way, or simply don't provide them an API for making changes.
INotifyPropertyChanged is primarily implemented by the ViewModel classes. This is to facilitate the data-binding so that the UI controls in the view that are bound to the ViewModel property will be updated when the property is modified.
In the MVVM design pattern, the relationships are very simple and in a single direction. The View knows it's ViewModel and a ViewModel knows about the Model. If the Model is updated, the ViewModel needs to know somehow so that it can reflect the update and propogate it to the View. One way is to also have the Model implement INotifyPropertyChanged and have the ViewModel implement the corresponding event handler. If all the changes are driven from the UI and being pushed back to the Model, then this is probably not necessary.
You can't really bind to a Dictionary. Using an ObservableCollection would be ideal if that works in your case. Or, you can take a look at implementing an Observable Dictionary along the lines of this: http://drwpf.com/blog/2007/09/16/can-i-bind-my-itemscontrol-to-a-dictionary/
MVVM has provided separation of the Model from the View, so there should be no direct relationship from the View to the Model. The implementation of the ViewModel controls what, if anything would ever get written back to your Model.
INotifyPropertyChanged (INPC) should never be in the model unless the model is also the ViewModel (i.e. you don't have a "model"). INPC should only ever be in the view model.
The model should know nothing about the view model, and thus can never communicate with it. Only the view model can communicate with the model.
From the UI point of view, only the view model does anything with data; so, if you want the model to be "read only", then just don't implement that in the view model.
Binding would be done with the view model, in which case don't use Dictionary (unless you want to write the code to wrap that in order to bind it). If the Dictionary is in the model, then you should be "wrapping" that in the view model--it's fairly trivial to write an observable wrapper around a collection. In all likelihood your view model isn't going to deal with key/value pairs--it should be dealing with something flat that the UI can handle (and be bound to).
UPDATE:
INPC was introduced for data binding. It decouples a view from a particular concrete class so that it only needs to know about INPC (notice the direction of decoupling). In terms of MVVM this decouples the view from the view model, in the case of PM, this could decouple the view from the presenter, in the case of MVC this could decouple the view from the controller, in the case of MVP this decouples the view from the presenter.
Data binding is a technique of binding data to UI elements. It binds a data source to a target so that the target may request data how ever it sees fit or the source can push data however it sees fit (depending on the type of binding--it could be one-way or static, restricting how often get/push can occur).
Sometimes the necessary nature of the decoupled relationship between the data source and the target lead people to believe data binding isn't a UI concern and data binding can apply anywhere. i.e. a data binding implementation is completely decoupled from a UI. This is generally a mistake. Data binding decouples the view from the specific knowledge of specific classes (this is basic layering and avoidance of cycles, that I won't get into here). But, it doesn't completely decouple the view from the data source. Binding can't happen without the data source--there is still a level of coupling there, it's just the compile-time coupling that has been alleviated (aids in testing, flexibility, robustness, etc. but must be present at runtime in production. i.e. the fact that the INPC implementation can be tested without being bound at runtime to UI elements doesn't mean it's not dependant on a UI framework). The fact that the view is still loosely coupled to the data source isn't the only coupling in this relationship. The data source is loosely (if not less loosely) coupled to the view by way of its UI framework.
Every UI framework has a restriction that access and modification of UI elements must be done on the main, or UI, thread. (at least on Windows; it likely happens on other platforms, I'm just not proficient in any others). With data binding, the source is indirectly bound to the control and any data change directly changes one or more UI elements (depending on the framework you can have intermediaries. Like value converters in WinRT, but their responsibility is to transform or convert data). This means that the data source needs to have intimate knowledge that it is bound to a UI and what type of UI framework it is binding to. This tight coupling to a UI framework clearly couples the data source (still loosely) to the UI.
This means any particular implementation of INPC is really bound to one and only one UI framework. That object can no longer be used anywhere (obviously anywhere is an ideal, it's often impossible to make anything work for every scenario--the point here is high cohesion in more than just one or two scenarios). e.g. if an implementation of INPC is used in a multi-threaded environment then it needs to "marshal" data back to the UI thread before sending out property notifications. In WinForms, that's Control.BeginInvoke, in WPF and Silverlight that's via System.Windows.Threading.Dispatcher. In WinRT, that's via Windows.UI.CoreDispatcher. In all cases the INPC implementation must take a direct coupling to one UI framework. In the case of Silverlight, that's a direct coupling to either the "desktop" Dispatcher or the Windows Phone Dispatcher.
Quality metrics include concepts like cohesion. Cohesion is a measure of how strongly related two units of code are. An implementation of INPC that is used by something other than the UI, due to the nature of all the infrastructure required to support that one particular UI framework, although potentially able to be used outside of the UI, will have low cohesion because all of the code relating to the UI framework will not be used. i.e. it's take on too much responsibility to be completely decoupled from the UI. Yes, you can use an object that implements INPC anywhere and never use the PropertyChanged event, but then you have low coehsion (considered bad).
If I implemented INPC in my model and I wanted to use that model with both my UI and my WCF or web service back end, I either couldn't or my backend would have to take a reference to some UI framework. If I wanted to use that model in another type of UI, I couldn't, because that INPC implemetnation depends on one particular UI framework. I'd have to write another "model"; at which point it's clearly a "view model".
INPC itself is not bound to a particular UI framework (nor should it be). This leads to the misconception that INPC can be used anywhere. Yes, its lack of coupling to high-level namespaces means it can, but the overwhelming usage of INPC is when the target is a UI. I'd challenge any other uses of INPC that don't involve a UI as true "binding". As with any other tool, you can misuse it to get useful results. INPC could be used for projecting data, it could be used for transforming data, etc.; but I believe those are misuses of INPC and really outside the focus of this question...
I have a solution where i pass a collection of items from a source to a presenter. When the source is updated I want to be able to notify the presenter to show the new result.
What comes to mind is to make a ChangeNotification class, pass it along with the result and have that class notify the presenter. Now as I see it this can be implemented in two ways, either ChangeNotification can have events that the presenter subscribes to, or it can have delegates that the presenter sets and the source calls if it is not null.
The benefits of using events is that more than consumer can react to the notification and you can hook up reactive extensions to it, the downside is that you have to manage subscribe/desubscribtion of the events for proper garbage collection. Delegates are simple but you lose some flexibility.
What is the most elegant pattern for situation like this? Is there some other way I haven't thought of?
If you will have multiple observers, Events or MultipleDelegates would be required. If you will only have one observer, and want to enforce that, a delegate would suffice. However, in terms of which is best, IMHO I would say the event is more flexible and lends itself very well to the pattern. The ObservableCollection and INotifyPropertyChanged are event based implementations. By the way, +1 to tbischel for the references to these classes.
There are two built in patterns for this scenerio.
First, you could implement the INotifyPropertyChanged interface. This is better if you want to notify the presenter of changes to properties of the objects themselves in the collection. (or the source object itself, if that is where changes occur).
The second is to pass your presenter an ObservableCollection containing your objects. This is better if you want to notify the presenter that an item has been added or removed from the collection. Both are event driven models that any subscriber could hook into.
Edit: The underlying pattern is the "Observer" pattern... you can roll out your own version if you want, you have the details down.
I agree with the other answers that INotifyPropertyChanged, INotifyCollectionChanged and other related interfaces are property the first place to turn but I wanted to add in third option which would be to implement the observer pattern. If your are not familiar with this pattern, it is how Java achieves it's event functionality through what are called event listeners. There is no reason why this pattern cannot be adopted in C# though and in some cases it may provide a more elegant solution than the use of events and delegate especially when there may be several coordinated events that are generally all subscribed to by an interested party.
Another option too is deriving from DependencyObject and implementing DependencyProperties in order to get the change notifications that are built-in and that are optimized for WPF. I tend not to go this route because I don't like the requirement of having a specific base class but there are some good arguments for why it is sometimes the right choice and in fact some MVVM frameworks even use it as the basis of change notifications for ViewModel classes too.
I'm been experimenting with the oft-mentioned MVVM pattern and I've been having a hard time defining clear boundaries in some cases. In my application, I have a dialog that allows me to create a Connection to a Controller. There is a ViewModel class for the dialog, which is simple enough. However, the dialog also hosts an additional control (chosen by a ContentTemplateSelector), which varies depending on the particular type of Controller that's being connected. This control has its own ViewModel.
The issue I'm encountering is that, when I close the dialog by pressing OK, I need to actually create the requested connection, which requires information captured in the inner Controller-specific ViewModel class. It's tempting to simply have all of the Controller-specific ViewModel classes implement a common interface that constructs the connection, but should the inner ViewModel really be in charge of this construction?
My general question is: are there are any generally-accepted design patterns for how ViewModels should interact with eachother, particularly when a 'parent' VM needs help from a 'child' VM in order to know what to do?
EDIT:
I did come up with a design that's a bit cleaner than I was originally thinking, but I'm still not sure if it's the 'right' way to do this. I have some back-end services that allow a ContentTemplateSelector to look at a Controller instance and pseudo-magically find a control to display for the connection builder. What was bugging me about this is that my top-level ViewModel would have to look at the DataContext for the generated control and cast it to an appropriate interface, which seems like a bad idea (why should the View's DataContext have anything to do with creating the connection?)
I wound up with something like this (simplifying):
public interface IController
{
IControllerConnectionBuilder CreateConnectionBuilder();
}
public interface IControllerConnectionBuilder
{
ControllerConnection BuildConnection();
}
I have my inner ViewModel class implement IControllerConnectionBuilder and the Controller returns the inner ViewModel. The top-level ViewModel then visualizes this IControllerConnectionBuilder (via the pseudo-magical mechanism). It still bothers me a little that it's my inner ViewModel performing the building, but at least now my top-level ViewModel doesn't have to know about the dirty details (it doesn't even know or care that the visualized control is using a ViewModel).
I welcome additional thoughts if there are ways to clean this up further. It's still not clear to me how much responsibility it's 'okay' for the ViewModel to have.
An option which works well for interaction between viewmodels is to bind directly to observer classes sitting between the viewmodel classes.
I think you want to make your top-level ViewModel aware of the existence of the NestedViewModel, it makes sense from a hierarchical standpoint, the master view contains the child view.
In my opinion, your instinct is right, it doesn't feel correct for the nested ViewModel to expose behaviours which are initiated by user actions on the top-level. Instead, the top-level ViewModel should be providing behaviors for the view it is associated with.
But I'd consider moving responsibility for connection construction into an ICommand, and exposing this command via your top-level ViewModel. The OK button on your master dialog you would then bind to this command, and the command would just delegate to the top-level ViewModel, for example, call ViewModel.CreateConnection() when it is executed.
The responsibility of your nested control is then purely collecting and exposing the data to its NestedViewModel, for consumption by the containing ViewModel, and it is theoretically more re-usable in different contexts that require the same information to be entered (if any) - let's say you wanted to re-use it for editing already-created connections.
The only wrinkle would be if the different types of NestedViewModel expose a radically different set of data.
For example, one exposes HostName and Port as properties, and another exposes UserName and Password.
In which case you may need to do some infrastructural work to have your top-level ViewModel.CreateConnection() still work in a clean manner. Although if you have a small amount of nested control types, it may not be worth the effort, and a simple NestedViewModel type-check and cast may suffice.
Does this sound viable?
I recently experimented with Unity (Microsoft Enterprise library) to use dependency injection. That might be a route to go when using interfaces that completely define what both viewmodels need to no from each other. MEF would be another option for dependency injection I'm aware of.
HTH