Why View-First when using ViewModel<T>?

Why View-First when using ViewModel<T>?

Old forum URL: forums.lhotka.net/forums/t/8239.aspx


triplea posted on Wednesday, December 30, 2009

Hi

I am a bit new to this so please don't hit back hard. I am checking the (very cool) ViewModel class and integrating it with a small PRISM app. From what I understand, the approach used is that of View-first, since the View is responsible for creating the ViewModel.
The problem with this is that you loose out on using an IOC to create the ViewModel and injecting the dependencies. This has been discussed and even solved in these usual reference posts:

http://blogs.msdn.com/erwinvandervalk/archive/2009/03/02/how-to-build-an-outlook-style-application.aspx
http://blogs.msdn.com/erwinvandervalk/archive/2009/04/29/how-to-build-an-outlook-style-application-with-prism-v2-part-2.aspx

Where the ViewModel appears to be set as the DataContext of the view.

I have a couple of questions at this point:

1. Was the View-first approach used intentionally? I appreciate that it may not be possible to get the ViewModel approach working, yet it would be quite cool.
2. Would setting the ViewModel as the data context on a View work? I will try this but since I am new to this I don't want to get completly lost on the wrong track.

sergeyb replied on Wednesday, December 30, 2009

I think you are going to get as many opinions on the matter as there are people using Prism J.

I personally use ViewModel first approach and inject view into ViewModel using dependency injection.  Thus, my views are not aware of view models, but view models are aware of views, although I only use this knowledge to set datacontext on the view to view model and that is it.  In my case I can take advantage of using container.Resolve on all types, views and viewmodels.

 

Sergey Barskiy

Principal Consultant

office: 678.405.0687 | mobile: 404.388.1899

cid:_2_0648EA840648E85C001BBCB886257279
Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: triplea [mailto:cslanet@lhotka.net]
Sent: Wednesday, December 30, 2009 11:15 AM
To: Sergey Barskiy
Subject: [CSLA .NET] Why View-First when using ViewModel<T>?

 

Hi

I am a bit new to this so please don't hit back hard. I am checking the (very cool) ViewModel class and integrating it with a small PRISM app. From what I understand, the approach used is that of View-first, since the View is responsible for creating the ViewModel.
The problem with this is that you loose out on using an IOC to create the ViewModel and injecting the dependencies. This has been discussed and even solved in these usual reference posts:

http://blogs.msdn.com/erwinvandervalk/archive/2009/03/02/how-to-build-an-outlook-style-application.aspx
http://blogs.msdn.com/erwinvandervalk/archive/2009/04/29/how-to-build-an-outlook-style-application-with-prism-v2-part-2.aspx

Where the ViewModel appears to be set as the DataContext of the view.

I have a couple of questions at this point:

1. Was the View-first approach used intentionally? I appreciate that it may not be possible to get the ViewModel approach working, yet it would be quite cool.
2. Would setting the ViewModel as the data context on a View work? I will try this but since I am new to this I don't want to get completly lost on the wrong track.



triplea replied on Thursday, December 31, 2009

Thanks for the feedback Sergey. I wasn't sure if this approach would allow you to take full advantage of the ViewModelBase<T> and ViewModel<T> classes but I am about to give it a go and see how this works. Just 1 more question, Rocky mentioned that Blend/VS2010 data binding support may not work with this approach (if I understood his statement correctly), is that something you take as a known limitation or do yuo work around this problem differently?

I have to admit that the Blend support is not on my list of priorities (I use it as yet) but if data binding in VS2010 is workable, it would be nice to do some work on a designer again!

RockfordLhotka replied on Wednesday, December 30, 2009

I approached the problem from a XAML-centric perspective, not code-centric.

If you assume the View is pure XAML, nothing else, then it is really challenging to do anything but view-first because there's no guaranteed way to hook the ViewModel to the View later.

Typically the ViewModel will be a resource at the form level (top level of the view). A lot of people that want VM first apparently decide on a convention where the resource is always named "RootViewModel" - which works, but seems fragile to me, since it relies on the XAML designer always naming it correctly.

The resource approach is nice because it means the VM is addressable throughout the XAML. You could make the VM the data context for the form itself, but you lose a level of addressability, and you lose any hope of doing data binding in a RAD way in Blend or VS10.

But I don't think the CSLA ViewModel<T> class requires view first. You just need to figure out how you are going to set the data context of the view to the viewmodel. That's not the viewmodel's job - so this implies that there's some other bit of code (a presenter or controller or renderer) that does hook up the viewmodel to the view.

I didn't want to create a complete UI framework - MVC/MVP/etc - so I essentially dodged that issue by choosing to support a XAML-centric worldview.

But I also don't want to lose the drag-and-drop designer support in VS10, and that is a XAML-centric model also.

To me, the big reason XAML (WPF/SL) is so cool is the massive UI code reduction. My continual goal is to have 0 (zero) lines of code behind the XAML. Absolutely none. This means a codeless view.

There are a couple ways to do this, the primary ones being the XAML-centric approach (let XAML create the objects it needs - that's what XAML is for after all), or an MVC/MVP approach.

The thing about MVC/MVP patterns is that they are really a lot more than Model/View/Controller or Presenter. That's the part a business developer writes. But to really make the "M" patterns work, you need a message router, a render engine and other components that are part of the framework. The "M" patterns are only productive if you have a framework that does all the hard work so you can just do the MVC/MVP parts :)

Look at ASP.NET MVC - an awesome implementation of MVC. A postback comes from the user and that causes a controller method to be invoked. But how does that happen? There's a whole message routing and translation engine in there first. Then your controller returns a View object. You never render the View - it might not ever render (think testing) - so this means the MVC framework has an entire rendering engine too - so it does the right thing with the View, the ViewData, ViewState, etc.

It is all very cool stuff. Lots of fun - but a framework unto itself, and so out of bounds for core CSLA.

My goal with ViewModel was to create a type that wraps a Model with commonly useful verbs/commands, and that works in a XAML-centric world. I have no doubt that it works in code-centric models as well, but then you need all that other plumbing :)

triplea replied on Thursday, December 31, 2009

Rocky thanks for the in depth explanation.

I am a bit confused with this statement:

RockfordLhotka:

The resource approach is nice because it means the VM is addressable throughout the XAML. You could make the VM the data context for the form itself, but you lose a level of addressability, and you lose any hope of doing data binding in a RAD way in Blend or VS10.

But I don't think the CSLA ViewModel<T> class requires view first. You just need to figure out how you are going to set the data context of the view to the viewmodel.

You mentioned loosing the Blend/VS2010 binding support if I set the VM as the View's datacontext but then suggest doing that in the next paragraph. Or is that an alternative approach if you are willing to loose the RAD stuff?

But I can see that some plumbing is probably unavoidable. I don't mind it and you are right that this stuff is cool. But it would be cooler with as fewer lines of code as possible :-)

Thanks a lot and have a happy new year!

 

Copyright (c) Marimer LLC