is this bad design? MVVM pattern w/ many commands on single class - wpf

There are two common command implementations I've seen by Microsoft. One, given by Josh Smith here,
places commands onto viewmodel classes. Another, given by Robert McCarter here, makes commands accessible via a static class (so we can data-bind to them with x:Static). McCarter's approach relies more on the use of singletons and static calls than I want to take chances with, so currently I've chosen to use Josh Smith's approach. However, my "main" viewmodel has blown up in size with at least 30 commands now, as I have a Ribbon control in the main window. Is this a sign of bad design i.e. a lack of separation of concerns? or is this common for MVVM apps? It just seems like a lot of responsibility for a single viewmodel.

I don't think it really matters if you have many commands in the same ViewModel. Commands are just boilerplate code, they don't really implement anything. If the actual implementation of these commands is in the same ViewModel, however, it could be an issue. You should probably try to break down your class into several components to apply the single responsibility principle.

If you have a ribbon control with a lot of commands on it, you're going to need to have a class that exposes all of those commands as properties. It doesn't necessarily have to be your view model; you could, for instance, create a ribbon view model and then expose an instance of it from your view model.
You can't really separate the concerns here unless you have commands on your ribbon that don't interoperate with the view model.

If you are worried of having many command on you MainWindow ViewModel and using a ribbon, you could try giving a separate ViewModel for every tab you have.
In an application I'm currently developing, for example, I separated each ribbon tab into a separate UserControl (which extends RibbonTabItem, because I'm using the Fleent Ribbon). Those views have their on ViewModels. Actually, those ViewModels are dependency injected using a MEF (Managed Extensibility Framework) importing constructor, as well as the tabs are dependecy injected to the MainWindow using its importing constructor. While this approach is probably a gigantic overkill, it has some flexibily. Note that referencing to command on a certain tab from the MainWindow itself isn't a problem, because the MainWindow's ViewModel can have a tab's ViewModel dependency injected into itself and expose some commands of it; or some command can come in form of a specific ViewModel that is injected into all the ViewModels that need it (the latter is probably the cleaner...)

Related

Where do I handle the WPF commands?

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/

Ambiguous between Microsoft Sample and WPF Rules

I thought we should have no reference from View to ViewModel in MVVM Pattern. but just saw an MVVM Sample from code.msdn.microsoft in which ViewModel implements new Window and shows it;
By using MVVM-Light toolkit you use Messenger to Call or Open new Window and Still keep Separate the View and ViewModel form each other. Is it right to reference the View in ViewModel? Or it is wrong;
Do you suggest to call Views Directly from ViewModel for large(or medium) projects?
http://code.msdn.microsoft.com/windowsdesktop/Easy-MVVM-Examples-fb8c409f
YAGNI.
Level of effort and complexity.
MVVM is just a pattern. A pattern you don't have to follow. Any little tool I write for my own use just uses a model, a viewmodel, and a view. The viewmodel exposes all properties I need for the view by INotifyPropertyChanged. The data is moved back and forth from viewmodel to model manually using ViewModel.FromModel(model) syntax. I don't bind to my models. I only use the model when saving/loading data; I don't hang onto it. My views are generated using dataTemplates and dataTemplateSelectors. If I have a property that should change the layout I expose that on the viewmodel and use a selector. Otherwise, I have a datatemplate for every viewmodel object. And it just works.
I call this a form of MVVM, even though it doesn't any toolkit or the exact MVVM pattern that Microsoft describes.
I would personally implement a service to drive commands from the viewmodel to generate new views and hookup the viewmodel. But that's because I have MVC experience, and I think generating views is easier to do using the MVC pattern, whereas desktop views work better using the MVVM pattern.
All my views are composed with contentControls. Setting the content is setting the viewmodel.
So I use a hybrid.
If your software isn't so complex to need the complete Microsoft endorsed MVVM pattern, why create the overhead code IMO. YAGNI.
IMO, having a strong reference from the ViewModel to the View has 2 problems:
It breaks the testability of your ViewModel code. This means you won't be able to Unit Test your code so easily, and if you do you'll have to account for Dispatcher issues and the like.
It makes your ViewModels dependent on WPF assemblies and types. This means you won't be able to literally copy and paste your ViewModels into other applications or platforms such as Xamarin.Android or the like
If none of these are important to you, I don't see any reason why you wouldn't. Not doing so creates additional overhead in your code, by having to implement WindowManagers and whatnot.

Semantically, should Commands and Converters be closer to Views or ViewModels?

I'm wondering if in MVVM I should design Converters and Commands be closer to Views or ViewModels. It's a gray zone for me as they are two types of glue objects bridging the gap between components. Maybe it doesn't really matter, but I'm wondering what Stack Overflow has to say about it.
I used to place Converters in the ViewModel namespace, because they are often reusable even if the View changes. However, I see more and more comments placing them closer to the Views. See top answers to:
Should your ViewModel expose XAML elements as properties or not?
How can WPF Converters be used in an MVVM pattern?
Commands are usually exposed by ViewModels to implement UI events, so I placed them in the ViewModel namespace as well. A classic examples are the RelayCommands. Then I came across an interesting pattern to use Commands to display dialogs between the main view and the ViewModel. I find that just brilliant by its simplicity. The command is really just a proxy, but clearly in UI land. Yay or nay? See:
MVVM and Dialogs
Handling Dialogs in WPF with MVVM
So where do you think Commands and Converters should live in MVVM? View? ViewModel? Doesn't matter?
I don't think you could say they are in one camp or the other. As you said, their purpose is to make the bridge between the ViewModel and the View, while keeping them uncoupled. And in my opinion that's how you should treat them, as glue code.
Converters - you could argue that they are closer to the view because their responsibility is related to how the information is adapted in order to be easily bound and displayed in xaml controls.
Furthermore, you could theoretically use two different converters for the same ViewModel property, depending on how you want to view it.
But nothing is stopping you to use them in other contexts if the need arises, somewhere where the View is not involved at all.
Since your question also implied where to put them, I put my converters separately, not in the views folder, nor in the ViewModels folder, to facilitate reuse.
Commands - are usually exposed by the ViewModel in MVVM, so that can be an argument that they are closer to the ViewModel, but in my experience, they are used most often to facilitate calling logic from the ViewModel via Bindings. If I could bind a ViewModel method call directly in xaml I would not use commands anymore - for simple cases.
Even though they are usually bound to the ViewModel, Commands might also be reusable between Views and ViewModels. If you find yourself copy-pasting the code for commands you can separate them, put the ViewModel behind an interface and reuse them.
Furthermore, the command pattern has many uses outside of the scope of MVVM. (For example, you could use it in the application logic to facilitate "Undo" functionality)
As for where to put them - usually I start by putting them in the ViewModel, and as things get more complicated I move them as needed. Here an interesting post about what you could do as things get complicated: How can I avoid command clutter in the ViewModel?
I know this is a subjective answer, but I hope I have provided some good arguments, and I am open to opinions.

MVVM - Pertaining to WPF command binding standards

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

Common shared views. Views + ViewModels or UserControls?

I am developing a little utility view that will be embedded in several of our apps. It will sit in a common library.
Should I expose this as a ViewModel along with a default View implementation, or would it be better as a UserControl with a fixed GUI?
It is pretty self contained and I doubt it will need to be reskinned, but doing it as a UserControl seems a bit overkill with having to set up a load of dependency properties.
A simple ViewModel seems more attractive to me but wondered if this was the normal way of sharing stuff?
EDIT:
It would also be nice if I could embed this in WinForms apps too. Is this possible with View/ViewModel?
Well, in the end I went with View/ViewModel. This keeps the separation nicely and is easily pluggable into existing MVVM projects.
It also works fine in WinForms, given that a View is just a UserControl with its DataContext set to some arbitrary object (the ViewModel).
The only slight issue I had was the fact that Application.Current is not set in a forms environment, so I had to store the GUI dispatcher reference so I could marshal gui updates to the proper thread in my ViewModel.

Resources