I have a whole bunch of RoutedUICommand commands which I fire from different places, using the Command attribute in XAML.
They all are bound right now in my MainWindow.xaml and in my MainWindow.xaml.cs I have a handler for each of them. I have set it up this way, mostly because I resolve the MainWindow class with Unity and it receives all necessary dependencies (i.e. domain services and etc). If I bind the command to a UserControl, I wouldn't have those services available there and also it seems wrong that a UserControl which is given a DataContext, but would be allowed to manipulate its or another context.
My question: does this seem right? To me, something seems off about handling all of the commands in a single central place, especially the main window code behind.
I am new to WPF and can't tell if this is right or wrong. Any advice is appreciated.
You should handle them in your ViewModel. The common pattern in WPF applications is MVVM.
M - model (i.e. DB)
V - view (.xaml files)
VM - a class that is set to be the DataContext for you view. You should do all the logic, binding here.
I suggest having a look at some MVVM frameworks that can simplify the development.
Some of the popular ones are:
Caliburn.Micro
MVVM Light
WPF provides two implementations of the ICommand interface; the System.Windows.Input.RoutedCommand and System.Windows.Input.RoutedUICommand where the latter is a subclass of the former that simply adds a Text property that describes the command.
However, neither of these implementations are especially suited to be used in a view model as they search the visual tree from the focused element and up for an element that has a matching System.Windows.Input.CommandBinding object in its CommandBindings collection and then executes the Execute delegate for this particular CommandBinding.
Since the command logic should reside in the view model, you don’t want to setup a CommandBinding in the view in order to connect the command to a visual element. Instead you should create your own command by creating a class that implements the ICommand. All MVVM libraries out there such as Prism, MvvmLight and Caliburn Micro already have such an implementation. They are usually called DelegateCommand or RelayCommand. Please refer to the following links for more information about commands and how to use them in an MVVM WPF application.
MVVM - Commands, RelayCommands and EventToCommand: https://msdn.microsoft.com/en-us/magazine/dn237302.aspx
Handling events in an MVVM WPF application: https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/
I think I have a pretty good understanding of the MVVM design model, however I have a quarm with it in regards to WPF, Command bindings and how we are meant to use them.
To bind commands to the XAML directly we are meant to implement the ICommand interface within the ViewModel. Now, the ICommand interface is part of the PresentationCore.DLL, which, correct me if im wrong is part of WPF not the base .NET framework.
Isnt the whole point of the ViewModel and Model that it should be totally UI independant? For example, if I implement ICommand in my ViewModel and use it as a data context in order to bind commands from the XAML, isnt my ViewModel then dependant on the WPF frame work (in particular the PresentationCore.Dll).
What I mean is, if I was to go and try to use my Models and ViewModels in lets say a Windows Forms environment, I would have to reference the PresentationCore.DLL even though I shouldnt need it because im using Windows Forms not the WPF framework.
This seems a bit odd to me, am I missing something here? Is there another way I should be doing it to keep my Model and ViewModel totally UI and UI Framework independant, but still be able to utilise the Command binding in XAML?
Thanks in advance!
I also had this kind of problem but not in wpf but in POCO classes. What i did was I created two partial classes in two different assemblies. Like you create one partial class which is not presentationcore.dll dependent in your VM project and create its partial class in another assembly(say WPFVM) which implements ICommand stuff. Now for Winforms stuff add only VM project reference to View project and for WPF stuff add references of both VM and WPFVM to the View project. I hope this will help.
The point of MVVM is to have the view just be a view, and nothing more. Putting ICommands into the view model helps this as it pulls the code away from the view. Where you will run into problems is if you have to access something on the view that is not a dependency property, which means you can not bind to it.
In my opinion MVVM is very popular with the WPF, Silverlight because it naturally fits into it. The data binding concept in the XAML allows the Views & ViewModels to be bridged using a single property which is the DataContext. As no longer your logic is tied to controls, you get better testability, design-code separation and maintainability. You may be able to implement the MVVM pattern in other places also, but in WPF and Silverlight, it fits so easily due to its data and command binding support. I have read somewhere that, Don't take patterns religiously. They were made to make your life simpler rather than giving you more problems while following it. For Winforms i think there are better patterns, If you are focusing in reusing the business logic, move them out of your ViewModels to seperate classes something like serviceproviders or serviceagents and share them between your Winforms and WPF apps.
This has changed in .NET 4.5 compare
.NET Framework 4.5
.NET Framework 4
I have a UserControl UserControl1 and a button inside the UserControl1. And I have a UserControl1ViewModel that has an ICommand property for the button. Using this command I need to call a method outside(from other VMs or VM of the MainWindow) the VM. What is the best practice for this?
You might want to examine MVVM lite by Laurent Bugnion http://www.galasoft.ch/mvvm/getstarted/
This is a lightweight toolkit for helping enforce mvvm concepts. In it, every viewmodel is a static member in a ViewModelLocator class. So for instance, in your command you could do something like this.
ViewModelLocator.MainViewModel.MainContent = NewContent;
You can totally do this without mvvm lite, but using it really helps speed up the learning curve and enforce modularity.
You're most likely looking to implement the Mediator pattern to handle the communication between two viewmodels.
Another SO question along the same vein is:
mvvm-view-model-view-model-communications
I would consider using Controllers for the mediation between the ViewModels. The WPF Application Framework (WAF) shows how this works.
I am currently working with the Microsoft MVVM template and find the lack of detailed examples frustrating. The included ContactBook example shows very little Command handling and the only other example I've found is from an MSDN Magazine article where the concepts are similar but uses a slightly different approach and still lack in any complexity. Are there any decent MVVM examples that at least show basic CRUD operations and dialog/content switching?
Everyone's suggestions were really useful and I will start compiling a list of good resources
Frameworks/Templates
WPF Model-View-ViewModel Toolkit
MVVM Light Toolkit
Prism
Caliburn
Cinch
Useful Articles
WPF Apps With The Model-View-ViewModel Design Pattern
Data Validation in .NET 3.5
Using a ViewModel to Provide Meaningful Validation Error Messages
Action based ViewModel and Model validation
Dialogs
Command Bindings in MVVM
More than just MVC for WPF
MVVM + Mediator Example
Application
Screencasts
Jason Dolinger on Model-View-ViewModel
Additional Libraries
WPF Disciples' improved Mediator Pattern implementation(I highly recommend this for applications that have more complex navigation)
MVVM Light Toolkit Messenger
Unfortunately there is no one great MVVM example app that does everything, and there are a lot of different approaches to doing things. First, you might want to get familiar with one of the app frameworks out there (Prism is a decent choice), because they provide you with convenient tools like dependency injection, commanding, event aggregation, etc to easily try out different patterns that suit you.
The prism release:
http://www.codeplex.com/CompositeWPF
It includes a pretty decent example app (the stock trader) along with a lot of smaller examples and how to's. At the very least it's a good demonstration of several common sub-patterns people use to make MVVM actually work. They have examples for both CRUD and dialogs, I believe.
Prism isn't necessarily for every project, but it's a good thing to get familiar with.
CRUD:
This part is pretty easy, WPF two way bindings make it really easy to edit most data. The real trick is to provide a model that makes it easy to set up the UI. At the very least you want to make sure that your ViewModel (or business object) implements INotifyPropertyChanged to support binding and you can bind properties straight to UI controls, but you may also want to implement IDataErrorInfo for validation. Typically, if you use some sort of an ORM solution setting up CRUD is a snap.
This article demonstrates simple crud operations:
http://dotnetslackers.com/articles/wpf/WPFDataBindingWithLINQ.aspx
It is built on LinqToSql, but that is irrelevant to the example - all that is important is that your business objects implement INotifyPropertyChanged (which classes generated by LinqToSql do). MVVM is not the point of that example, but I don't think it matters in this case.
This article demonstrates data validation
http://blogs.msdn.com/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx
Again, most ORM solutions generate classes that already implement IDataErrorInfo and typically provide a mechanism to make it easy to add custom validation rules.
Most of the time you can take an object(model) created by some ORM and wrap it in a ViewModel that holds it and commands for save/delete - and you're ready to bind UI straight to the model's properties.
The view would look like something like this (ViewModel has a property Item that holds the model, like a class created in the ORM):
<StackPanel>
<StackPanel DataContext=Item>
<TextBox Text="{Binding FirstName, Mode=TwoWay, ValidatesOnDataErrors=True}" />
<TextBox Text="{Binding LastName, Mode=TwoWay, ValidatesOnDataErrors=True}" />
</StackPanel>
<Button Command="{Binding SaveCommand}" />
<Button Command="{Binding CancelCommand}" />
</StackPanel>
Dialogs:
Dialogs and MVVM are a bit tricky. I prefer to use a flavor of the Mediator approach with dialogs, you can read a little more about it in this StackOverflow question:
WPF MVVM dialog example
My usual approach, which is not quite classic MVVM, can be summarized as follows:
A base class for a dialog ViewModel that exposes commands for commit and cancel actions, an event to lets the view know that a dialog is ready to be closed, and whatever else you will need in all of your dialogs.
A generic view for your dialog - this can be a window, or a custom "modal" overlay type control. At its heart it is a content presenter that we dump the viewmodel into, and it handles the wiring for closing the window - for example on data context change you can check if the new ViewModel is inherited from your base class, and if it is, subscribe to the relevant close event (the handler will assign the dialog result). If you provide alternative universal close functionality (the X button, for instance), you should make sure to run the relevant close command on the ViewModel as well.
Somewhere you need to provide data templates for your ViewModels, they can be very simple especially since you probably have a view for each dialog encapsulated in a separate control. The default data template for a ViewModel would then look something like this:
<DataTemplate DataType="{x:Type vmodels:AddressEditViewModel}">
<views:AddressEditView DataContext="{Binding}" />
</DataTemplate>
The dialog view needs to have access to these, because otherwise it won't know how to show the ViewModel, aside from the shared dialog UI its contents are basically this:
<ContentControl Content="{Binding}" />
The implicit data template will map the view to the model, but who launches it?
This is the not-so-mvvm part. One way to do it is to use a global event. What I think is a better thing to do is to use an event aggregator type setup, provided through dependency injection - this way the event is global to a container, not the whole app. Prism uses the unity framework for container semantics and dependency injection, and overall I like Unity quite a bit.
Usually, it makes sense for the root window to subscribe to this event - it can open the dialog and set its data context to the ViewModel that gets passed in with a raised event.
Setting this up in this way lets ViewModels ask the application to open a dialog and respond to user actions there without knowing anything about the UI so for the most part the MVVM-ness remains complete.
There are times, however, where the UI has to raise the dialogs, which can make things a bit trickier. Consider for example, if the dialog position depends on the location of the button that opens it. In this case you need to have some UI specific info when you request a dialog open. I generally create a separate class that holds a ViewModel and some relevant UI info. Unfortunately some coupling seems unavoidable there.
Pseudo code of a button handler that raises a dialog which needs element position data:
ButtonClickHandler(sender, args){
var vm = DataContext as ISomeDialogProvider; // check for null
var ui_vm = new ViewModelContainer();
// assign margin, width, or anything else that your custom dialog might require
...
ui_vm.ViewModel = vm.SomeDialogViewModel; // or .GetSomeDialogViewModel()
// raise the dialog show event
}
The dialog view will bind to position data, and pass the contained ViewModel to the inner ContentControl. The ViewModel itself still doesn't know anything about the UI.
In general I don't make use of the DialogResult return property of the ShowDialog() method or expect the thread to block until the dialog is closed. A non-standard modal dialog doesn't always work like that, and in a composite environment you often don't really want an event handler to block like that anyhow. I prefer to let the ViewModels deal with this - the creator of a ViewModel can subscribe to its relevant events, set commit/cancel methods, etc, so there is no need to rely on this UI mechanism.
So instead of this flow:
// in code behind
var result = somedialog.ShowDialog();
if (result == ...
I use:
// in view model
var vm = new SomeDialogViewModel(); // child view model
vm.CommitAction = delegate { this.DoSomething(vm); } // what happens on commit
vm.CancelAction = delegate { this.DoNothing(vm); } // what happens on cancel/close (optional)
// raise dialog request event on the container
I prefer it this way because most of my dialogs are non-blocking pseudo-modal controls and doing it this way seems more straightforward than working around it. Easy to unit test as well.
Jason Dolinger made a good screencast of MVVM. Like Egor mentioned there is no one good example. They are all over. Most are good MVVM examples, but not when you get into complex issues. Everyone has their own way. Laurent Bugnion has a good way to communicate between viewmodels as well. http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx Cinch is also a good example. Paul Stovel has a good post that explains a lot too with his Magellan framework.
Have you looked at Caliburn? The ContactManager sample has a lot of good stuff in it. The generic WPF samples also provide a good overview of commands. The documentation is fairly good and the forums are active. Recommended!
Found this one useful. Has code too.
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
I have written a simple MVVM example from scratch on code project here is the link MVVM WPF step by step.
It starts from a simple 3 layer architecture and graduates you to use some framework like PRISM.
The sample project in the Cinch framework shows basic CRUD and navigation tools. It's a fairly good example of using MVVM, and includes a multi-part article explaining its usage and motivations.
I also shared in your frustration. I'm writing an application and I had these 3 requirements:
Extensible
WPF with MVVM
GPL compatible examples
All I found were bits and pieces, so I just started writing it the best I could. After I got into it a bit, I realized there might be other people (like yourself) who could use a reference application, so I refactored the generic stuff out into a WPF/MVVM application framework and released it under the LGPL. I named it SoapBox Core. If you go to the downloads page, you'll see it comes with a small demo application, and the source code for that demo application is also available for download. Hope you find that helpful. Also, email me at scott {at} soapboxautomation.com if you want more info.
EDIT: Also posted a CodeProject article explaining how it works.
Here I am adding link of a WPF(Inventory Management App) application which using MVVM architecture designed by me .
Its UI is awesome.
https://github.com/shivam01990/InventoryManagement
Even I shared the frustration until I took the matter into my hands. I started IncEditor.
IncEditor (http://inceditor.codeplex.com) is an editor that tries to introduce developers to WPF, MVVM & MEF. I started it and managed to get some functionality like 'theme' support. I am no expert in WPF or MVVM or MEF so I can't put a lot of functionality in it. I make a sincere request to you guys to make it better so that nutters like me can understand it better.
Anyone who has tried to implement RoutedCommands in WPF using M-V-VM has undoubtedly run into issues. Commands (non-UI commands that is) should be implemented in the ViewModel. For instance if I needed to save a CustomerViewModel then I would implement that as a command directly on my CustomerViewModel. However if I wanted to pop up a window to show the users addresses I would implement a ShowCustomerAddress command directly in the view since this a UI specific function.
How do I define the command bindings in the viewmodel, and use them in the view?
Here is a solution that I came up with.