Saturday 9 June 2012

Post/Email-2: Views, ViewModels and Composition


Recently a friend of mine asked me the following question on Facebook:

brother, hope i am not disturbing you. had a question. if i have mutliple tab items in one page in y silverlight app, while each tab serves different functionalities, would it be all right if i write separate view models for all of the tab items, and i expose this view models as properties from one view model and bind the page's datacontext to that main viewmodel?

Thursday 7 June 2012

Post/Email–1: MVVM Light messaging, order of register and send is important

 
Recently a friend of mine asked me the following question on Facebook. I started writing a few sentences, which turned into a few paragraphs and before I knew it I was writing a very long reply. Then, something Scott Hanselman said on twitter came to mind:
"Every email you send is a blog post you didn't write. Stop writing emails.”
Because of this, I intend to write these “Post/Email” (or “Post over Email”) blog posts whenever someone asks me a question, so that other people would benefit from them :)
Here we go, with this question from my friend Saad Galib on facebook:
...is it at all possible to pass data between ViewModels using MVVM light messaging without ViewModelLocator? Because in a blog i read that that some class needs to register for a message before it is sent to receive it. Right now i have no locator. i send a message from ViewModel-1 bound to page 1 and then navigate to page 2 which in turn creates viewmodel 2 and in that viewmodel's constructor i register for that kind of messages(broadcasted from viewmodel1)....but its not working....:(
and this i definitely not satisfying the condition i read as i mentioned above. is there any work around?
The short answer is: no. The "no" here isn't because of the ViewModelLocator itself, but rather because of what you mentioned later about the order in which the subscription and broadcast are done.
The Messenger implementation in MVVM Light is simple and straightforward. When you register an object to some event, it adds it to a dictionary; and when that particular event is sent, it goes through the corresponding objects in the dictionary and notifies them (by calling the corresponding registered action). Therefore, when an object subscribes to a certain event, it only gets notified of those instances of the event which occur after it has subscribed. Which is the logical thing to do.
I'm not aware of anything in MVVM Light that would help with your particular situation, but there are other, maybe not so elegant, methods to transmit data between objects in a loosely coupled way. One of them, which I used myself but I'm not sure whether it's a good practice or not, is to have some sort of "buffer" where an object can put some data for other objects to take out at some point in time (in my particular scenario, I used a class "Pipe" with a static member "Data" that I set in one VM and consume in the other).
Hope this helps