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.
Related
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.
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
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 ?
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.
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. :)