Notification from ViewModel to View - wpf

I need to send notification from ViewModel to View in MVVM WPF application. In most cases it will be simple MessageBox on View side. Is it unacceptable violation of MVVM pattern to use types like System.Windows.MessageBoxResult or System.Windows.MessageBoxImage in ViewModel (in this case VM must reference UI-specific libraries)?
I need to pass title, message and notification type from VM and by creating custom enumerations I am in fact copying existing functionality from .NET Framework.

You don't need notification mechanism. That's one option. Another is using simple service class:
public class ViewModel
{
IDialogService _dialogService; //ctor injection or use service locator
public void CommandExecute()
{
_dialogService.ShowMessageBox(...);
}
}
public interface IDialogService
{
bool? ShowMessageBox(params....);
}
public class DialogService : IDialogService
{
public bool? ShowDialog(params...)
{
MessageBox.Show(params...);
}
}
I find this approach more straightforward, easier to understand and easier to debug. Messaging may easily turn into memory leak and in this case I don't see any benefit over my approach.
EDIT:
Will you use custom enum in ShowMessageBox parameters, or will you use
System.Windows.MessageBoxImage?
First of all, ViewModels belong to presentation layer. It is OK to use enums like System.Windows.MessageBoxImage in ViewModel.
In MVVM, ViewModels are separated from Views because of following reasons:
ViewModels expose data and logic from Model in such way that is easily consumable from Views (e.g DataBinding)
ViewModels are easier testable
ViewModels provides better design time support (Blendability, test data)
ViewModels separates application logic from the actual presentation markup which makes it easier to understand (readbility)
Does using enum like System.Windows.MessageBoxImage breaks any of the points above? The answer is no.
If you wanted to reuse IDialogService and your ViewModels on multiple platforms, for example WPF, UWP and Xamarin, then you need to create your own enum, because it may not exist on all platforms. The golden rule is: don't add another layer of abstraction if you don't need it.

You could have the view implement an interface, say INotificationService and then pass the view to the view model constructor. That won't violate MVVM, and you will still be able to bind the view model to the view using the DataContext property on the view.

I decided to keep ViewModel as clean of UI (View) stuff as possible, so I will create custom enumeration inspired by MessageBox and tailored exactly to my needs.

Related

Correct way to handle commands that rely on multiple view models

I'm relatively new to WPF and MVVM and i am trying to understand how to use commands correctly when they have dependencies in more than 1 view model.
A couple of examples:
In my current application i have a RelayCommand which causes a save action to occur in a couple of different view models (they write a couple of different files). Currently i am handling this using a the mvvmlight messenger to send a message to those view models to get them to do the save which i think is the correct way to do it as it avoids having to provide some kind of delegate or event to/on those view models.
I have a RelayCommand in a view model that has a CanExecute method which relies on the state of 2 other view models. I've currently handled this via the mvvmlight messenger as well by having changes in the view models the CanExecute method depends on message that their state is now valid for the operation. This seems messy but the only alternative i could think of was to use a delegate or event effectively weaving the view models together which i believe i should be avoiding.
Is there some generally accepted way to deal with this which i am missing?
In general your view model layer should have a 1:1 relationship with your view, there should be no good reason for a "Save" function to exist in a view model which is then called by another view model.
What it sounds like you should be doing is putting that logic into a service i.e. something like this:
public interface ISerializationService
{
void Save(SomeData data);
}
Then you need an implementation for this service that does the actual work:
public class SerializationService : ISerializationService
{
void Save(SomeData data)
{
// actual save happens here
}
}
Your view models should then contain properties that point to instances of these services:
public class MyViewModel : ViewModelBase
{
[Inject]
public ISerializationService SerializationService { get; set; }
// called when the user clicks a button or something
private void ButtonClickCommand()
{
this.SerializationService.Save(this.SomeData);
}
}
The only question remaining is "What sets the value of SerializationService?", and for that you need a dependency injection framework. There are plenty out there, MVVMLight installs one itself, but Ninject is the de-facto standard. When implemented properly the injection framework will create all view models for you and then "inject" the dependencies, i.e. your SerializationService property, of type ISerializationService, will be initialized with an instance of your SerializationService class (which in a case like this will also be configured to be a singleton).
Dependency Injection takes a bit of work to get your head around but once you start using it you'll never look back. It facilitates complete separation-of-concerns whilst alleviating the need to pass pointers to everything all up and down your architectural hierarchy.

MVVM model instantiation

Following WPF MvvmFoundation, linking the View with the ViewModel has many choices like described on http://www.paulstovell.com/mvvm-instantiation-approaches.
However their example has nothing about how to link the ViewModel with the Model.
Traditionally I created the model first and then one or more views that render it. It seems that MVVM pushes people to create the View, which creates the ViewModel, which create the Model. I hope it's not the case as wiring a complex business model with various ModelView can else be tough.
How do you instantiate your business model classes in MVVM and link them with your ViewModels?
I normally pass Model objects as constructor params to VM. I use App class as the controller which will initialize MainWindow, MainWindowViewModel with the main model. There after the MainWindowViewModel takes care of initializing other VMs with appropriate model objects.
private void Application_Startup(object sender, StartupEventArgs e)
{
mainWindow = new MainWindow();
mainWindow.DataContext = new MainWindowViewModel(new Model());
mainWindow.Show();
}
You create your BusinessModel classes inside your ViewModel.
So in your CustomerViewModel you would say this.CurrentCustomer = new CustomerModel(), and your CustomerView would bind to the CurrentCustomer property on the ViewModel
If you are interested, I wrote up a simple sample using MVVM as an example of how the View, Model, and ViewModel interact.
I use dependency injection/MEF to do this. Just export all of my model classes all the way down the chain, and have them imported for me automatically into the ViewModel constructor.
I take a variety of different approaches depending on the situation. I've found that when it comes to getting this data linked, one size does not fit all.
For simple cases, I will have the ViewModel and the Model be the same thing. Obviously not that good for all cases, but sometimes there is just no need to go the extra mile to split the M from the VM. (Great for cases where you have, say, listbox items that have scant information)
Sometimes, especially when the model is a chunk of code you don't have access to (written by another developer) it is easy to subclass the model, and add all of your VM things (observable properties, etc.) on to it.
Lastly, I will use the approach that is mentioned by Souvik. Construct the VM with the model information that you want to use as a parameter, or allow it to be passed in otherwise. This is probably the most common approach for my larger and more complex Model / ViewModel relationships.
I am auto-passing IRepository instance to VM constructor using IoC container and everything VM needs to do with models is done via this repository. Repository is class which: Create, read, update and delete data. When I need to show some view (window), I use IViewService.ShowDialog(viewModel As ViewModelBase). In implementation of IViewService, there are views registered with VMs, so VMs only need to know other VMs and not their views (like "Show me view for this view model").

MVVM: Communication between the Model and ViewModels

I'm developing a WPF application using the MVVM pattern. I'm using MVVM Light library and I'm also trying to use a dependency injector (I'm considering Ninject and Unity).
I've read a lot of blog articles and I'm quite confused about the "proper" way of making my classes communicate with each other. In particular, I don't know when to use Dependency Injection and when to rely on the mediator pattern.
Lets consider an example. I have a ViewModel, lets call it DataViewModel, and the Data class that provides some kind of data.
How is it better to communicate between them:
A. Inject a dependency to DataViewModel with an interface of IData? This way Data will not have to rely on Messenger, but it will have to provide an event if the Data changes, and the ViewModel will have to subscribe to it.
B. Rely on the mediator pattern (implemented in MVVM Light as Messenger) and send messages between Model and ViewModel? This way it will not be necessary to use Dependency Injection at all, because whole communication will be based on messages.
Moreover, should my ViewModels have injected dependencies on other ViewModels, or it would be better just to rely on the Messenger? If the first, would it be necessary to define a separate interface for each ViewModel? I think that defining an interface for each VM will be an additional work, but maybe it is worth it.
Generally the ViewModel goes to a Service (as Prism calls it) to retrieve the data it needs. That service is pushed to the ViewModel via DI (Constructor Injection) although you could perform this another way via a ServiceLocator.
Therefore your ViewModel will hold a reference to a service which will abstract away the retrieval of your data. The data could be coming from a DB, XML file, who knows...the abstraction is there. So for your case of IData, the reference to that type will occur at some point in the ViewModel but not by way of any from of DI. If your IoC framework allows it (Prism does) you create mappings of interface types to concrete types and then retrieve those types via your container; such is the case with Unity.
Here is a brief example...Scripts is bound to the View and the ViewModel is injected into the View. Notice the use of the IScriptService to retrieve the data. The data coming back is a collection of IScript types, however we never formally injected that type into the ViewModel because we don't care about the type as a single entity we care about the type on a grandeur scale.
public ScriptRepositoryViewModel(IUnityContainer container, IScriptService scriptService, IEventAggregator eventAggregator)
{
_container = container;
_scriptService = scriptService;
_eventAggregator = eventAggregator;
}
public ICollectionView Scripts
{
get
{
if (_view == null)
{
_view = CollectionViewSource.GetDefaultView(_scriptService.Scripts);
_view.Filter = Filter;
}
return _view;
}
}
When you make your way to the View, the same case can be had there, the View will get injected via DI (Constructor Injection) with the ViewModel. I would not make other ViewModels depend on each other, keep them isolated. If you begin to see a need for coupling take a look at the data you are trying to share, more often then to that data needs to be abstracted out further and not become coupled to any ViewModel.
There is more than one good solution to your problem,
I suggest you to use some single interface in your data models, put it in a base class, this interface will allow your data objects to communicate with the outside world.
For the view models inject not the data but an interface that can retrieve data for you, the data will expose events that the vm can register to them after he gets them.
data oject should not know who holds him, view model knows what kind of data he holds but I dont recommend to inject this data due to flexibility issues.

INotifyPropertyChanged vs. DependencyProperty in ViewModel

When implementing the ViewModel in a Model-View-ViewModel architecture WPF application there seem to be two major choices how to make it databindable. I have seen implementations that use DependencyProperty for properties the View is going to bind against and I have seen the ViewModel implementing INotifyPropertyChanged instead.
My question is when should I prefer one over the other? Are there any performance differences? Is it really a good idea to give the ViewModel dependencies to WPF? What else do I need to consider when make the design decision?
Kent wrote an interesting blog about this topic: View Models: POCOs versus DependencyObjects.
Short summary:
DependencyObjects are not marked as
serializable
The DependencyObject class overrides and seals the Equals() and
GetHashCode() methods
A DependencyObject has thread affinity – it can only be accessed
on the thread on which it was
created
I prefer the POCO approach. A base class for PresentationModel (aka ViewModel) which implements INotifyPropertyChanged interface can be found here: http://compositeextensions.codeplex.com
According to the WPF performance guide, DependencyObjects definitely perform better than POCOs that implement INotifyPropertyChanged:
http://msdn.microsoft.com/en-us/library/bb613546.aspx
The choice is totally based on your business logic and UI abstraction level. If you dont want a good separation then DP will work for you.
DependencyProperties will be applicable mainly at the VisualElements level so it won't be good idea if we create lot of DPs for each of our business requirements. Also there is a greater cost for DP than a INotifyPropertyChanged. When you design a WPF/Silverlight try to design UI and ViewModel totally separate so that at any point of time we can change the Layout and UI controls (Based on theme and Styles)
Refer this post also - https://stackoverflow.com/questions/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel . The link has a lot of reference to Model-View-ViewModel pattern, which is very relevant to this discussion.
From an expressiveness standpoint, I thoroughly enjoy using dependency properties and cringe at the thought of INotifyPropertyChanged. Apart from the string property names and possible memory leaks due to event subscription, INotifyPropertyChanged is a much more explicit mechanism.
Dependency properties imply "when this, do that" using easily-understood static metadata. It is a declarative approach that gets my vote for elegance.
Dependency properties are intended to supports binding (as a target) on UI elements not as a source to data binding, this is where INotifyProperty comes in. From a pure point of view you shouldn't use DP on a ViewModels.
"In order to be the source of a binding, a property does not need to be a dependency property; you can use any CLR property as a binding source. However, in order to be the target of a binding, the property must be a dependency property. For a one-way or two-way binding to be effective, the source property must support change notifications that propagate to the binding system and thus the target. For custom CLR binding sources, this means that the property must support INotifyPropertyChanged. Collections should support INotifyCollectionChanged."
All dependency objects cannot be serialised (This could hamper the use of ViewModels and DTO (POCO)'s.
There are differences between DP within Silverlight compared to WPF.
http://msdn.microsoft.com/en-us/library/cc221408(v=VS.95).aspx
http://msdn.microsoft.com/en-us/library/cc903933(VS.95).aspx
INotifyPropertyChanged when used also gives you the ability to add more logic in the code of your getters and setter of your properties.
DependencyProperty example:
public static DependencyProperty NameProperty = DependencyProperty.Register( "Name", typeof( String), typeof( Customer ) );
public String Name
{
set { SetValue( NameProperty, value ); }
get { return ( String ) GetValue( NameProperty ); }
}
In your getter and setter --- all you can do is simply call SetValue and GetValue respectively, b/c in other parts of the framework the getter/setter is not called, instead it directly calls SetValue, GetValue, so your property logic wouldnt reliably be executed.
With INotifyPropertyChanged, define an event:
public event PropertyChangedEventHandler PropertyChanged;
And then simply have any logic anywhere in your code, then call:
// ...
// Something cool...
// ...
if( this.PropertyChanged != null )
{
PropertyChanged( this, new PropertyChangedEventArgs( "Name" ) );
}
// More cool stuff that will reliably happen...
This could be in a getter/setter, or anywhere else.
Is it really a good idea to give the ViewModel dependencies to WPF?
.NET 4.0 will have System.Xaml.dll, so you won't have to take a dependency on an arbitrary framework to utilize it. See Rob Relyea's post about his PDC session.
My take
XAML is a language for describing objects, and WPF is a framework whose described objects are UI elements.
Their relationship is similar to C#, a language for describing logic, and .NET, a framework which implements particular kinds of logic.
XAML's purpose is declarative object graphs. The W*F technologies are great candidates for this paradigm, but XAML exists independently of them.
XAML and the entire dependency system were implemented as separate stacks for WF and WPF, probably to leverage the experience of different teams without creating a dependency (no pun intended) between them.
I too had to consider this decision recently.
I found that the INotifyPropertyChanged mechanism suited my needs better because it allowed me to glue my GUI to an existing business logic framework without duplicating state. The framework I was using had its own observer pattern and it was easy to forward one level of notification on to the next. I simply had a class which implemented the observer interface from my business logic framework and the INotifyPropertyChanged interface.
With DP you cannot define the backend that stores the state yourself. I would have had to let .net cache a copy of every item of state I was binding to. This seemed like an unnecessary overhead - my state is large and complicated.
So here I found INotifyPropertyChanged better for exposing properties from business logic to GUI.
That being said where I needed a custom GUI widget to expose a property and for changes to that property to affect other GUI widgets DP proved the simple solution.
So there I found DP useful for GUI to GUI notification.
Dependency properties are the glue of custom control creation. If you are interested in using Intelli-sense to show your properties in the properties window at XAML design time you must use Dependency properties. INPC will never show a property in the property window at design time.
It seems that Dependency Properties should be used in controls that you create such as Buttons. To use properties in XAML and use all the WPF features, those properties must Dependency Properties.
However, your ViewModel is better off using INotifyPropertyChanged. Using INotifyPropertyChanged will give you the ability to have getter/setter logic if you need to.
I recommend checking out Josh Smith's version of a base class for a ViewModel that already implements INotifyPropertyChanged:
http://joshsmithonwpf.wordpress.com/2007/08/29/a-base-class-which-implements-inotifypropertychanged/
I think this is an excellent example of how to do a ViewModel.
I think DependencyProperty and INotifyPropertyChanged are used for two different things in Binding : the first for enabling a property to be a target of a binding and receive the input from another property (use {Binding ...} to set the property), the last when you want the value of a property to be used as the source of a binding (name in the Binding Path Expression).
So the choice is merely technical.
I prefer a more direct approach, which I blogged about in Presentation Model Without INotifyPropertyChanged. Using an alternative to data binding, you can bind directly to CLR properties without any bookkeeping code. You just write plain-old .NET code in your View Model, and it gets updated when your Data Model changes.
There is only one thing why to prefer a DependencyObject - Binding will work better. Just try an example with a ListBox and TextBox, populate list with data from INotifyPropertyChanged property vs. DependencyProperty and edit current item from TextBox...
If you want to expose properties to other controls you must use Dependency properties... But good luck because they take a while to figure out...

How to further decouple this WPF example toward MVC, MVP, or MVVM?

I've decoupled events in this WPF application in the following way.
What is the best way to continue decoupling?
Shell.xaml:
<Button x:Name="btnProcess"
Content="Process"
Margin="10"/>
Bootstrapper.cs:
public void Run()
{
Shell shell = new Shell(new Customer());
shell.Show();
}
Shell.xaml.cs:
public Shell(IPerson person)
{
InitializeComponent();
btnProcess.Click +=new RoutedEventHandler(person.Process);
}
Customer.cs:
public class Customer : IPerson
{
public void Process(object sender, RoutedEventArgs e)
{
Button theButton = (Button)sender;
theButton.Content = "Customer processed.";
}
}
The above code successfully decouples the view Shell from the model Customer:IPerson so that I can swap in e.g. a model Employee:IPerson etc. which handles "Processed" in its own way. That was the first goal.
But now:
how do I decouple the Processed method from talking specifically to a Button, so that it could also talk to a MenuItem or a ListView which fires the event in the view and so that it doesn't even have to be an element at all that calls it, e.g. a unit test class?
how do I alter other elements of the view other than the sender (Button), e.g. how would I alter the status bar in Shell? I see two ways:
I could either build a container which holds all views and inject the container in the Customer upon creation, then the customer can look in the container and manipulate the calling view anyway it wants (although I would have to somehow match the view that sent the event and the view in the container as the same one)
I could somehow send the whole view (Window object) to the Model with the eventargs when firing the event, although the Model would need some way of knowing (via interface) what kinds of regions were available to manipulate at runtime
How would you continue this application in the direction of a more decoupled design?
What pattern is this actually, e.g. MVC, MVP, MVVM? I only see a view (Shell) and a Model (Customer).
How would a Presenter fit in?
How would a ViewModel fit in?
How would a Controller fit in?
I suggest you to implement your event handling using commands instead of classic events.
Its very easy in WPF because the command pattern is already implemented, and you can tell all of your UI inputs (button, menu item...) that their command is [name of your command] and handle all of them in one place.
Cameron MacFarland did a good job here, but I can add a little.
When following M-V-VM, the tools in your box for decoupling are data binding, commands, attached behaviors and interfaces. Data binding should be self evident. You've already gotten a good description of commands, but I'd suggest you avoid RoutedCommand and stick with an ICommand implementation. Attached behaviors are attached DependencyProperty's that subscribe to events on the element they are attached to, and in this scenario would be used to relay event handling to the ViewModel. Interfaces give you the greatest flexibility, but you have to work out how to pass the interface to the ViewModel. The best way to learn all of this right now is to Google and to look at existing M-V-VM frameworks. Here's a list of frameworks:
Prism/Composite WPF (http://www.codeplex.com/CompositeWPF). This one comes from the Microsoft Patterns & Practices group. Lots of good stuff here, but one of the examples of the three things above that you can learn from here is how to use ICommand. Prism includes a DelegateCommand that implements ICommand and simplifies using commands from a ViewModel in M-V-VM.
Caliburn (http://www.codeplex.com/caliburn). Recently released, one of the key things you can learn from this one is how to use attached behaviors, which this library uses for it's "Actions".
Onyx (http://www.codeplex.com/wpfonyx). Disclaimer: I'm the author of this one. This one hasn't been released yet, though the current alpha source is available. This one provides a novel solution to the problem of how to provide interfaces to your ViewModel.
As Chen suggests, i'd look into the Command pattern: Routed commands
A working example from which i learned a lot can be found on Jaime Rodriquez his blog: Southridge
how do I decouple the Processed method from talking specifically to a Button
Commands. Put a command in the IPerson interface and call that command from the Shell's xaml.
how do I alter other elements of the view
Properties and Binding. If you have a property showing the state (processed/not processed) then you can use binding to display that property directly in the xaml.
How would you continue
I'd head more down the MVVM path by creating a ViewModel between the Shell and the IPerson. The ViewModel is designed to have 1) The properties needed for bindings, and 2) any Commands that need executing. The ViewModel is designed to provide the UI with what it needs from the Model.
What pattern is this
Currently? Nothing. I see only two objects, the View and the Model. You don't have a Presenter, Controller or ViewModel.
For WPF I prefer ViewModel. See this question for more info on MVVM.

Resources