Push common ViewModel functionality into a base class? - silverlight

I'm using MVVM with Prism and Silverlight. I have multiple different views of one model. As I am writing more views their ViewModels seem to duplicate a lot of common code related to handling this one model. Rather than repeating the same common code in all the VMs I am tempted to push it back into the model (which would probably mix concerns too much). Or maybe into some common ViewModel base class? Or perhaps my VMs need a 2nd level of "shared VM" between them and the model? This single shared instance, 2nd-level-VM would consolidate the behavior and state shared by the multiple regular VMs.
Any comments about these issues and possible approaches?
Thanks for the comments guys. I probably should have told you more about the specific "shared" VM code in question.
I can see putting some future code in a VM base class, but the particular "shared" code I'm looking at seems to belong in an INotifyPropertyChanged implemented by the model itself. This is partly based on this other thread.
I don't think this violates SoC, because the model is inherently dynamic. Some of its properties are only valid at certain times. That dynamic nature of the model is not just something that's important for the UI, a proper unit-test would also care about it. Hence this model seems to need an INotifyPropertyChanged.
Any comments on that?

If the common code can be shared by all ViewModels, then it's worth putting it into a base ViewModel type.
If the common code is only shared by ViewModels that interact with a particular Model, then a "shared" ViewModel is the way to go.

I've used inheritance for ViewModels in the New York Times Silverlight Kit successfully to reduce replicated code. Look at the CommunityRecentComments and its parent class CommunityBase for an example.

Most "base ViewModel" classes in the variety of MVVM frameworks tend to contain the support for INotifyPropertyChanged and usually some sort of support for dispatching back to the UI thread.
Beyond that I think that if you have a number of ViewModels that share functionaltiy that should be into a base class, the more I use this pattern the more I find myself using a rather shallow hierarchy of ViewModels, a base ViewModel for code common to all view models and typically another base class under that for common functionality in that area of the UI. Usually common commands or where the UI is sharing elements.
ViewModelBase -> ProductsViewModelBase -> NewProductViewModel

In SoapBox Core, which is fully MVVM, I defined an IViewModel interface, and an AbstractViewModel base class which, as Nigel said, just implements INotifyPropertyChanged. (Note that SoapBox Core is WPF, not Silverlight, but in this case it's not a big deal. I've done some similar Silverlight work as well.)
Then I defined more interfaces (like IMenuItem) that inherit from IViewModel and more abstract classes that provide a basic implementation of those interfaces.
Now, that accounts for the whole ViewModel tree, but as you said, there's also the Model tree. I've spent almost a year working with MVVM now and here's my big epiphany: Don't write a Model. If you're building the application from the ground up, just put everything in the ViewModel, otherwise you end up duplicating a ton of code.
The only cases where I bothered having a Model was when I was using a 3rd party library that didn't implement INotifyPropertyChanged and therefore wasn't easily bound to. I believe that auto-generated code for entity frameworks might fall in here as well, but I noticed that some entity frameworks now give you the option of implementing INotifyPropertyChanged in the entities themselves.
Seriously, we should rename it the ViewModel pattern and be done with it. :)

Related

Caliburn.Micro - Wrap Model or expose it directly?

I'm currently facing one of the most discussed problems in MVVM: I have a complex Model in my WPF application and I'm not sure how I should display its data to the View.
According to many answers here on StackOverflow and also to this article there are two ways:
to wrap the Model inside the ViewModel by adding a property in the ViewModel for each property in the Model
to expose the Model directly to the view without replicating the properties.
What I understood so far is that the first approach is better from a theoretical point of view, while the second one is a quick shortcut that should be avoided.
In the same article I previously linked, the author writes the following:
In reviewing the sample application from the Caliburn framework, they implement the VM using option 2.
I took a look at the Caliburn.Micro documentation and unfortunately it just uses a simple ViewModel without a real Model, so I don't know how to verify this statement.
Is the author right? Since I'm using Caliburn.Micro should I use the second approach instead of the first one in order to be more "compliant" with the framework implementation?
Since I'm using Caliburn.Micro should I use the second approach instead of the first one in order to be more "compliant" with the framework implementation?
No. Caliburn.Micro is just an MVVM library. How you implement the actual MVVM pattern is entirely up to you.
I agree with #Marek Dzikiewicz that you should wrap the model in a view model class that may implement the INotifyPropertyChanged interface and provide any other UI specific functionality. This code doesn't belong to a business object. You could refer to my answer here for more information:
Reuse the same models in ASP.NET MVC and WPF MVVM
Obviously if the model class is indeed a UI specific class that is not used in any other application and doesn't contain any business logic that is used on the server side, you could modify this class and bind to it directly. But then it is kind of a (sub) view model after all.
Usually it is better to expose view models because that allows you to add additional properties to control the way the data is displayed (for example formatting or concatenating data). However, if you don't need that, there is nothing wrong in exposing the model classes directly.

View and ViewModel getting too large

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 ?

How does EF work in WPF/Silverlight apps?

I've been trying for a while to wrap my mind around 2 concepts at once, learning MVVM (and one of the hard things has been trying to figure out which framework to use. We didn't even know how many there were until a few weeks ago) and also I'm trying to learn Entity Framework 4.2.
This is for a WPF app that we're going to be writing.
I've gotten Julia Lerman's book and I'm also going through an online training course on EF, but one thing I still don't get, and haven't seen any example of yet, is how to handle something like the INotifyPropertyChanged interface with the classes created via EF, regardless of whether we use MVVM or not, working with INotifyPropertyChanged is vital.
So, let me ask here the plain question:
Do you allow EF to create all of the data access classes that reflect all of the data in your database, and then duplicate much of that code so I can get it to work with INotifyPropertyChanged? Or is there some other way of doing that?
I was baffled when the thought came to me, that I'd have to map every data object to a new one only implementing INPC on top of it.
Then I found a trick: assuming you're going to use WCF, it automatically implements INPC.
For the collections, just go into the Service Reference configuration, and set it so that it gives you ObservableCollection as default collection type.
That's it, you're set for MVVM =)
Because the ViewModel is created with the needs of the View in mind, only in very simply cases the ViewModel and your Entity are the same class. Normally you have an Entity class and a ViewModel class.
INotifyPropertyChanged is only one of the reasons for this. There are others like conversions, validation, meaningful error messages, aggregation etc.
I have previously used Entity Framework in several of my WPF applications. The first time I used EF Database first. It was pretty tricky to get the model exactly the way I wanted it, and once it was working, then I had to go through and implement INotifyPropertyChanged on my entity classes.
Recently, I have started using EntityFramework CodeFirst with 4.1, I have found it is much much easier to handle all of the property changed stuff. I generally create a base class with INotifyPropertyChanged implemented on it and inherit my entities from that.
As far as the ViewModel, I also started out worrying about this framework or that framework. Later I decided to just roll my own. Sure, the frameworks have some interesting capabilities, but for learning, I found it much easier to get into it by creating my own ViewModelBase class and inheriting all of my ViewModels from that.
ViewModelBase typically implements INotifyPropertyChanged. Later I created a ViewModel monitor class which would have a collection of ViewModels. To look them up, I gave ViewModelBase a FriendlyName property so that each type of inherited ViewModel could have a name set for it (my types are typically RecordMaintenanceViewModel, NavigationViewModel, ShellViewModel, etc) and I generally will inherit my used view-specific ViewModels from those. So on the ShipmentView in my shipping program, The ShipmentViewModel is inherited from a CollectionViewModel, which is inherited from the ViewModelBase. In this way I have functionality divided up into discreet sections allowing me to handle specific scenarios.
I generally port my ViewModel base over to every project, and often take my middle ViewModels; sometimes I have to recreate them though.

Are the advantages of Model-View-ViewModel (MVVM) pattern worth the overhead?

The question is stated in the subject: are the advantages of Model-View-ViewModel (MVVM) pattern worth the overhead?
In many cases, implementing the view model involves quite significant overhead of duplicating the Model properties and sometimes synchronization between Model and ViewModel data members. For example, currently in Silverlight 4 & WCF RIA, View Models are not generated (if the developer follows the MVVM pattern, it is up to him to create the view models, often duplicating the corresponding Model's properties at ViewModel, that do nothing significant but refer to Model as the storage).
Why not extending the Model class, providing additional properties to make it easy to be consumed by the View instead?
Why not extending the Model class, providing additional properties to make it easy to be consumed by the View instead?
Effectively that is what the PresentationModel is for. Which MVVM is strongly based on. The difference is that the ViewModel is the model for the view and not the model for the data. So you are concerned around more how the view behaves with the data.
If you have a simple UI that all it does is present the model then I would suggest expose the Model on a property of the ViewModel and bind to that. Make sure though the model does implement INotifyPropertyChanged etc.
The power of the ViewModel is when you have things to do in response to a user action. The ViewModel can then support Commands, calling out to services and validation and thus leaving the Model as a data container
Why not extending the Model class, providing additional properties to make it easy to be consumed by the View instead?
In the simple cases, this is all the ViewModel is doing - wrapping up the Model so that its extended in a way that's consumable by the View. If your Model can be bound directly, you're welcome to do so.
That being said, there is more to the ViewModel layer than just wrapping the model - this is also where the application specific logic - ie: the application's plumbing, will occur. Something has to make the requests from the Model classes correctly and compose together the logic.
If you are concerned about extra work, you can always create a ViewModelBase (INotifyPropertyChanged , Errors/Validation, generic stuff) to be inherited by your ViewModel, it will minimize things that you think may cost you time to replicate. And also, Silverlight/Wpf provides us with binding which greatly reduces our coding, besides the fact that XAML also does that by providing functionalities through markup. Besides that you can further the design by using screens, controllers, etc.
For me, I do not see any "overhead" with regards to using MVVM; if there were, it'd be worth it. It properly deals with the Separation of Concerns. It provides a good platform for development especially in teams where people may take care of different aspects of the application without affecting other team members codes (especially between developers and designers).
Hope this helps
Benefits of MVVM
Reduced complexity.
Isolation of Designing and Development.
Dependency injection.
Major advantage is when you have a Well MVVM structured Windows Phone application and want to develop same for Windows Metro Desktop, Only thing u want to concentarte on design as the same view model can be used as it is.
Hope it helps.

What MVVM framework is Good For?

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.

Resources