NOOB Challenge Implementing MVVM in WPF - wpf

To preface, this is my first attempt at MVVM... I buy it, I'm just having a little trouble implementing it.
I'm building a utility to assist with managing a course. I have a COURSE object which contains a few properties and methods as well as a collection of MODULES. Each module has a few properties, methods and a reference to a PRESENTATION object and LAB object (each of those has a few properties. I first implemented the modele and wrote all unit tests.
My challenge is now in implemting the UI (V & VM)... specifically the view-model part of the MVVM.
The UI allows you to create a course, see the modules and then have a master-detail view into each module where you can set a few properties and such. For my view model, I created an object to encapsulate the COURSE model... exposing a few properties including an ObserveableCollection of the course modules.
I've run into a few things that are throwing me for a loop and looking for some help:
I'm not sure if I went about my VM part correctly by creating something that encapsulates the COURSE model. Because I need to access MODULES in the course as well as LABs and PRESENTATIONs in the COURSE object. Does that mean I need to create VM's for each of those as well? Seems like I'm going about this the wrong way as this approach means I'm going to encapsulate every object in the model, same goes for each method and property?
When showing the modules in the UI of the app, I need to move things up and down in the order. The methods that do this are baked into the COURSE model. The trick is when I use these methods from the view, it isn't updating the view because the courses object lives in the VM, not in the M. I can "fix" this by setting the DataContext of my listview to null and then resetting it to be the same as the hosting window (which is the COURSE), but that isn't ideal. The modules are an observable collection, but they won't update because I'm doing the work at a lower level.
Seems I'm going about my VM a bit wrong... something tells me that not everything from the model should be encapsulated within it.

You don't NEED to create VMs for Modules or Labs, having Observable collections of each is enough. But...If you need to have extra powers on each of these objects, you can have collections of ViewModels instead. (as the Josh Smith example do)
If your logic is in the model, you need to refresh the ViewModel when you do changes to the model.

Related

Is the Model in MVVM a Domain model or POCO?

Is it OK to use my Domain Model as Model in the MVVM pattern, in the context of a WPF application? Or is the Model (in MVVM) supposed to be some POCO? I personally don't see any reason against using the Domain Model as Model of the MVVM WPF pattern.
But then the XAML elements will bind to what? Properties in the VM, which underneath are mapped to the Domain Model, right?
To answer the question posed in your title: neither.
In MVVM, the "model" is generally everything the other side of the viewmodel (i.e. between the viewmodel and the repository). The model can (and usually is) composed of several different additional architectures and patterns, it is normal to have services, micro services, DALs and DILs, domain models, POCOs/data entities etc all within the "model".
The domain objects and POCOs you speak of are not the model, they are part of the model. The perspective of the model that you talk of has been brought over from other patterns like MVC, where a data entity or domain object is indeed the model. The model is a little more complex than that in MVVM.
You can bind directly to a POCO in MVVM, but it's not usually a good idea unless it is a very simple one that is not subject to change (like a lookup list that is sourced from a repository). And it is usually quite a bad idea to bind to domain objects because these will contain extra functionality or information that is related to storage and retrieval but is overkill for anything shown in the UI. The other problem with domain objects is they usually don't serialize nicely (if at all - often domain objects are generated), so unless you have a very simple model it is best to transform the domain objects to POCOs as soon as practical.
So as mentioned in the answer from Owen, you should wrap your POCOs with viewmodel classes before they are made available to the UI. The only time you shouldn't is when you don't need any property change notifications and you also don't want to leverage any further functionality on the objects (for example you won't need a context menu on the displayed item).
But then the XAML elements will bind to what? Properties in the VM, which underneath are mapped to the Domain Model, right?
Yes, you could reference your POCO model entity classes in your WPF application and wrap them in view model classes that implement the INotifyPropertyChanged interface to provide support for dynamic change notifications. This is perfectly fine.
Please refer to my answer to the below question for more information about this.
Correct way to update property in ViewModel from Model
You'll likely want to wrap your domain model objects with view models. The purpose of your view model is to expose data from your model in a way that is useful to the view. For very simple applications it might seem cumbersome to add that extra layer just for change notification, but as your application becomes more complex, having a view model layer to bind to can help keep your model clean. If you are doing something quick and dirty, there is nothing stopping you from binding directly to your domain model objects.
Yes as long as your domain model implements inotifypropertychanged you can use and bind xaml with VM properties

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.

Push common ViewModel functionality into a base class?

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

ViewModel and user interface project locations

Im writing a wpf project and using the MVVM paradigm, what i was wondering is if i should write my view model classes in their own project.
Advantages i can see is that your ui project would never have to know about your business logic. (not have a reference to it)
however if i want to use the ICommand interface in my view model i still need a reference to PresentationCore which may indicate that i should be in my ui project.
comments suggestions most appreciated.
As soon as you reference PresentationCore in your ViewModel (which is currently unavoidable if you want to use ICommand) you are leaking all manner of undesirable View-related features into your ViewModel. For example, MessageBox.Show, when you see this called in a unit test it drives home why it's bad.
To answer the question, yes keep your View and ViewModel in separate projects. I wondered this myself but after going down the separate projects route it took me awhile to appreciate but it has been really valuable in making me stick to a clean MVVM solution, and the lessons from this have greatly improved my overall solution architecture. It's all about reducing dependencies on unnecessary assemblies using interfaces and if necessary the Adapter pattern. One example is that my View project, being an entrypoint has a reference to Ninject, but I don't want my ViewModel to have that reference. Otherwise someone might come along and use the Ninject static Kernel directly.
Regarding ICommand, I don't know the history having only used WPF since 4, but it feels like MVVM was an afterthought. I'm not sure why else Microsoft would have put this interface in PresentationCore. I'm hoping this will be addressed in a future release with a separate assembly for the ViewModel layer.
I don't think there's an overwhelmingly compelling way to do it one way or the other. I tend to keep VMs and their views in the same assembly, but within a different folder structure. For example, I might have ViewModels/Foo/Bar/CustomerViewModel and Views/Foo/Bar/CustomerView.xaml.
I don't think there's a problem splitting out the views and view models either. Having the VM assembly reference view-related assemblies such as PresentationCore is only natural. After all, your view models are part of your view layer.

Using Ninject to inject dependencies into externally constructed objects (user control)

I would like to use Ninject in my WinForms application. I cannot figure out how to use it for my user controls. Sometimes they rely on the services I want to configure through the DI framework. These controls need to be manageable through the designer (thus need default constructors).
So, is there a way to inject dependencies into properties of this user control? Since the designer needs to be able to construct it, kernel.Get<TestClass> won't work here. Is there a method or some code that will let me "fill-in" the dependencies in the Form_OnLoad() method?
I can also think of other examples where I would want to Inject into the properties of an already existing object, but th WinForms user control is the easiest to explain.
I think you need to invert your thinking. In Model View Controller, the View has only one responsibility: to display data.
How that data gets there is the Controller's responsibility, and how the data is represented in memory is determined by the Model.
Although there are no specific MVC frameworks for Windows Forms, it's possible to make crude ones manually, or you could go have a look at the (now retired) Composite Application Block to get an idea about how this can be done (although the CAB is perhaps too complicated for most people's tastes). There are more elegant options available today, but they involve WPF.
In any case, instead of injecting your dependencies into your Views, inject them into Controllers, and have the Controllers instantiate and correctly populate the Views (your Controls).
In this way, you can keep your Controls free of DI concerns, as they should be.
I think the question is what DI tool can you use to get dependency injection to work with windows forms. Everyone does the MVC example because it's easy to implement(the same example if floating around the we as if it were new and original). If you have an answer for doing it using winforms or even WPF - that would be helpful.
This answer here basically says - in any case, I don't know so inject them into controllers and populate the views - really? Back to the MVC? Again - winforms.

Resources