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.
Related
While adding extra functionality to the main view I have in my application, I've realized that the amount of code will soon become a problem (currently around 600 lines of code in my viewmodel and I still have plenty to add).
I've been looking around for articles on how to split/design your view into smaller components, but I haven't found a satisfying solution. One person suggested using child viewmodels but that presented with other problems (dependency between the viewmodels).
I've thought of using user controls, but there is nothing on the View that I use on other Views so it kind of defeats the purpose of user controls.
What is a correct approach in this situation?
Thanks,
Adrian
If you want to split a view into component parts, then you need to do view composition. If you are building an MVVM app, then you should really be using an MVVM framework. Something like Caliburn.Micro makes view composition incredibly easy.
There doesn't necessarily have to be dependencies between the view models, they should only know about what they need in order to produce their view. This could be a subset of the business object that the parent view model contains. As the parent view model will have references to all of the child view models, it can pass the relevant parts of the business object to them at the point of their construction.
I would agree with using Caliburn Micro.
However, to play devil's advocate you could split out your ViewModel File into separate files (same class name) and use the partial keyword before the class keyword. Its generally tidier and one step-away (non-breaking precursor) from breaking-up into separate classes.
I also agree Caliburn.Micro is a good solution for splitting your application in smaller components.
In Caliburn.Micro the communication between viewmodels is based on the Event aggregator pattern.
This makes a loose coupling between viewmodels
Splitting up is not ideal.
It looks as if the Caliburn toolkit focuses on events, whereas my application largely relies on ICommand implementations.
To me, the first encounter with Caliburn.Micro has been unsatisfactory.
The setup appeared to be tailored to VS2010 - which sounded promissing to me - because I do have VS2010 pro. But I got lost in the setup's of Silverlight.
Compared to toolkits like Prism it lacks the ease of an start.
It just takes to much time to switch now.
I use my own MVVM paradigm, it is less abstract than the Caliburn, it integrates multilanguage support everywhere, and it just faces one acceptable problem of some sources getting too big because of the nature of the Binding/DataContext paradigm.
For this problem I accept that "partial class" is a solution - even though I know there is a more elegant solution available.
In the heat of my work, I cannot change to another toolkit.
So I gently wait for Microsoft to allow for more flexibility around that Binding/DataContext paradigm.
It may be the case that Caliburn shows more intelligence allocating a viewmodel to some item. Does it ? (I think it does.)
What might be another option is to define a custom (xaml useable) object that triggers a custom allocator which control is to be allocated to which viewmodel. How about that ?
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...)
i know some Mvvm Frameworks that introduced in this thread
please describe or give me link for that what are them useful for?
not information about MVVM about MVVM Framework.
thanks :)
i want to know :
What Is MVVM Framework?
I think your question is not really precise. As far as I understand, you ask for the features of each framework?!
You can find detailed information here and here. However, at least one of these links has already been given in the thread you mentioned...
EDIT:
Basically, an MVVM framework is a collection of classes which are commonly used in applications utilising the MVVM (Model-View-ViewModel) pattern. This may include messaging systems to communicate between independent parts of a software, dependency injection techniques, base classes for ViewModels, project/class templates, validation mechanisms, commonly used commands, techniques for displaying dialog boxes, and so on...
To completely understand such a framework, you will have to understand the MVVM pattern first. Because only then (or even only after you did your first MVVM project) you will have an understanding of the problems and/or challenges of this pattern.
To use Mvvm framework just simply follow below steps:
You have a model and a view-model with the same name.
View-models are not supposed to be wrappers around models. The job of a view-model is to broker requests for external services such as the loading and saving of data. The data itself, as well as validation and most of the business logic, should be in the models.
I can’t emphasize this enough. Whenever you create a view-model that wraps a model by delegation you introduce a huge hole in your API. Specially, anything with a direct reference to the model can change a property in such a way that the view-model and thus the UI are never notified. Likewise, any changes to calculated fields in the model won’t be propagated back to the view-model.
You have a view and a view-model with the same name.
Ideally view-models are agnostic to the screens they are used by. This is especially true in a WPF application where multiple windows may be sharing the same instance of a view-model.
For smaller applications such you may only need a single view-model for the whole application. For larger applications you may need one for the main functionality and one for each secondary aspect such as configuration management.
You have no code behind.
In absolute terms code behind is neither a good nor a bad thing. It is merely a place to put logic that is specific to a single view or control. So when I see a view with no code-behind at all I immediately check for the following mistakes:
Does the view-model touch specific controls by name?
Is the view-model being given access to controls via a command parameter?
Is EventToCommand or another leaky behavior being used in place of simple event handler?
EventToCommand from MVVM Light is especially bad because it will prevent controls from being garbage collected after they are removed from the screen.
View-models are listening to property changed notifications
If a model has a longer life-span then the view-model that listens to its events then you probably have a memory leak. Unlike views which have an unloaded event, view-models don’t have a good story for life-cycle management. So if they attach an event to a model that may out-last them then the view-model will be leaked.
I have read the MSDN article on MVVM and I am not really convinced.
If the model already implements INotifyPropertyChanged/INotifyCollectionChanged, what's wrong with the View binding directly against the Model?
It seems the extra ModelView introduces some code without much benefit.
Am I missing something?
I was also a bit skeptical about MVVM until I watched this great presentation by Jason Dolinger. I recommend all my co-workers who are starting out in WPF and MVVM to watch it.
Jason started with an application that
one would write in a “traditional”
way, with button clicks handled by
event-handlers in the code-behind that
then updated other parts of the UI.
Using WPF data-binding, Commands, and
Unity, he transformed it, piece by
piece, in a much more manageable,
encapsulated, readable, and testable
M-V-VM design. It was awesome.
To answer your question more directly, even if it seems silly to bind to a ViewModel when your Model already has everything, you'll often wind up needing one little adjustment to the Model that's needed only by the View. Over time, these little changes will creep into your Models, where they don't belong. It'll make your models more complicated than they ought to be.
What I often do when I have a Model that "has it all", is I add a ViewModel that contains one property, the Model. Then in my bindings I just bind to Model.Name, Model.Age, etc. It's really no effort. Later on, if I need tweaks only for the View, I already have my ViewModel class ready. This also makes your code more intuitive and easier to understand. You won't wonder, did I bind to the Model or the ViewModel in this case? It will always be the ViewModel.
INotifyPropertyChanged and INotifyCollectionChanged are not the only aspects to be considered... In many cases, the data exposed by the model will not be easily usable by the view. The role of the ViewModel is to act as an adapter between the model and the view : expose the data in a form that allows the view to easily bind to it, expose commands to which the view can bind in order to perform actions... Typically, a model won't expose ICommands : if it does, then the model is WPF-specific, which is never a good thing is you want to reuse in some other non-WPF application...
I have been using MVVM for a few months, and it made my life much easier : no more "spaghetti code" in code-behind files, clear separation of responsibilities, clean overall architecture...
I have been using MVVM for 2 projects and here are a few things that I have been doing in the ViewModel:
Transforming the data from the model (When you are using a ViewModel, it makes life easier when UI specifications change, you don't need to change the Model/Persistence code)
Implementing a ICollectionView over a collection provided by the model
Implementing Commands
Caching (maintain expensive to calculate data)
Maintaining a dictionary on model data (for fast lookup)
Lazy-loading (not load until it's been used by the View)
Managing Undo/Redo
Validation of data (IDataErrorInfo)
and there is much more to do there (that I forgot) that would not fit in the Model itself, or would make the user interface spaghetti.
Not to forget, the ViewModel enable you to unit test things that you would not be able to test if it was implemented in the UI (such as Commands).
Finally, using MVVM, I was able to build a command-line version of my application very easily by using the ViewModels.
I'm using MVVM with MEF for a few years now and am not really sure how helpful it really is.
In our development we don't reuse ViewModels for different Views, neither do we have designers who are only allowed the change the View (UI).
And a lot of things are hard to achieve in a ViewModel, like setting the cursor focus depending on changes in the ViewModel (yeah, it is possible, but adds a lot of clutter to the code).
The good thing about MVVM is organising the values and commands as bindings instead setting the fields directly, but this could be done without the ViewModel.
Well this question relates to MVVM pattern and i could good and fast answers on this forum so I thought to ask and clear the confusions i had about the pattern.
I am quite new to MVVM approach. I appreciate the pattern and understand the principals behind it. Maybe I have not worked that much with the pattern that’s why there are a few confusions.
If there is a scenario in which I want to load few parts of my WPF page dynamically with XAML and still want to be compliant with MVVM approach.
The confusion is:
Where the logic of loading a view dynamically with XAML reside.
Whether I should have a single ViewModel for my WPF page or each seperate part have its own viewmodel with interactions with other viewmodel classes.
What if I had to build control tree displayed on the GUI using C# code in the codebehind itself.
For the controls created using code should I do the commandbindings in the codebehind of the view itself.
Where the logic for loading goes is something not really addressed by the pattern itself. There's an interesting blog post about this by Ward Bell. There's any number of ways to skin this cat, and they're all compatible with MVVM. Not really the answer you're looking for, I know, but it's honest :). Check out Ward's blog post... you'll get a much more in depth discussion of this topic.
As for whether or not to have a single VM for the page, or one for each control, that just depends. Generally, I have one for the page. If there's some portion that reusable elsewhere, I break it out into a user control with it's own VM, which means we have a VM within a VM. I don't agree with rockeye on this one. There isn't a one-to-one relationship between V-VM-M. You're Models are designed according to business needs, with NO regard to presentation at all. You're ViewModels are designed according to your presentation needs, and may encapsulate more than one Model. In fact, it's very common for them to encapsulate many models.
Like rockeye, I don't understand your last question.
I am also quite new to mvvm, but i will try to answer :
Where the logic of loading a view dynamically with XAML reside
If you mean "how can i show the view associated with my business object?", IMHO, you don't have to care about this. Usually, your VMs have corresponding views. With dataTemplate, you use only VM in the code but Views are displayed automatically.
2 Whether i should have a single ViewModel for my WPF page or each seperate part have its own viewmodel with interactions with other viewmodel classes
It seems you have a top-bottom approach. I see the mvvm more as bottom-up : models (business objects) -> ViewModels -> Views. Every model should have its own ViewModel and view. So you can't have a whole WPF page in a viewModel unless you model represents a page.
3 What if i had to build control tree displayed on the GUI using C# code in the codebehind itself. For the controls created using code should i do the commandbindings in the codebehind of the view itself.
Don't understand. I think you may take a look at dataTemplate, it might be helpfull.