tags:

views:

62

answers:

2

I have an App which has a Tasks tab and a Projects tab. I decided to make a separate ViewModel for each of the tabs, TasksViewModel and ProjectsViewModel.

The Tasks tab has a new task area with an associated project pulldown and the Projects tab (obviously) has a list of projects.

What I'd like is for the pulldown on the Tasks tab to share the same collection as the Projects tab list so that any time I add or remove a project on the Projects tab the list on the Tasks tab is up to date automatically. This worked well with a single ViewModel but it was beginning to become quite unruly.

Should I not have split into two ViewModels? Is there a common method of sharing data like this? Perhaps pass the same ObservableCollection<Project> into each of the ViewModels? Perhaps some type of notification back to the TasksViewModel along the lines of ICollectionChanged.

Appreciate any insight/input!

+2  A: 

The easiest solution here is often to use some form of Messaging Service to pass information between the two ViewModels.

For example, the MVVM Light Toolkit provides an IMessenger interface for situations like this.

Using a good IoC or DI toolset can help in this situation, as well. That would let you inject the project collection dynamically into both of your ViewModels, allowing a shared collection to be used in both Views.

Reed Copsey
I agree, but ONLY if the data is really part of the view model, not part of the model. If it is actually part of the model I would say passing it back and forth between view models would be a very bad idea: Much better to share a single model throughout the whole applcation. I explain this further in my answer. (Yes I do realize DI is a good way to accomplish the sharing of the common model, but I think it is very important to identify it as such.)
Ray Burns
Thaks Reed, I like the messaging idea. I've used similar feature in the WebformsMVP framework.
joshperry
+1  A: 

It seems to me that your concepts of "Tasks" and "Projects" are part of your model, not part of your view model.

Consider this conceptual exercise: Suppose your app was written so that two users could use your application on two separate machines against a shared database, and one user adds a Project:

  1. Would it be a good or a bad thing if the Project immediately showed up in the dropdown on the Tasks tab of the other user's screen?
  2. Would it be a good or a bad thing if the Project showed up in that dropdown after the first user hit "Save" or "Commit" or "Ok"?

If the answer to either of these questions is "yes", your data is really part of your model not your view model. And it should be handled as such.

Your view model should incorporate your actual model by reference, and it is a good thing to share the model objects between view models as much as possible. In fact, ideally most of your application has a single set of model objects. The exception might be a dialog box where you want to be able to make some changes but then hit "Cancel" and not save them. In that case, the "Ok" button would copy data from the model maintained by your dialog box into the main application model.

Now let's consider the case where you answered "no" to both of these questions. This would be an application where you never save your "Projects" list back to the main database/document/whatever, but it is a transient list used only for temporary work. In that case it would really be a view model, and I would attach it to the application (or whatever scope was appropriate) and have the two tabs access it.

Ray Burns