Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One ViewModel, multiple views

I am having a hard time getting multiple views to work against 1 viewmodel. I have read Naming Convention for Multi-View Support without getting much out of it, and have tried countless things in the process.

Just to take a simple example. Say I have a ViewModel for People residing in ShellViewModel, which basically contains a list of Person-objects. I want to display them in two different ways in my application.

enter image description here

What is the correct way to name the Views in this case, and how do I display both views in ShellView?

like image 445
Walkingsteak Avatar asked Sep 13 '13 14:09

Walkingsteak


People also ask

Can one ViewModel have multiple views?

Micro offers multiple views for one view-model via "cal:View. Context" property. Maybe you can have a look in their source code, how this is technically achieved.

Should each view have its own ViewModel?

Yup, each view should have its on ViewModel. I don't know WPF inside out, but generally the ViewModel mediates between a UI component and a business logic component. In other words: It's specific to a view/model pair - this is the only reason for this component to exist...

What should not be in a ViewModel?

Caution: A ViewModel must never reference a view, Lifecycle , or any class that may hold a reference to the activity context.

Can a ViewModel contain another ViewModel?

It's sub-par. I have seen many times the suggestion on this forum to have on ViewModel as a member of another ViewModel. Whilst this solves the problem at hand, I believe it is a violation of the MVVM pattern. Another ViewModel is not UI-related functionality that the ViewModel shoule be directly.


2 Answers

Anders is correct, there are a number of default conventions for Caliburn.Micro, one of them will locate and display <RootNS>.Views.[<ChildNS>].<ViewTypeName> for <RootNS>.ViewModels.[<ChildNS>].<ViewModelTypeName>.

In your case, for a single View (assuming the classes reside in namespaces derived from the folders):

<RootNS>.Views.PeopleView would by located and displayed for <RootNS>.ViewModels.PeopleViewModel.

For multiple views over the same viewmodel, the convention is that views of format <EntityName>.<Context> are displayed for viewmodels of format <EntityName>[<ViewSuffix>]ViewModel:

From your example, you could create a new folder named People, and inside it, create your views named Grid and List.

Your namespaces become <RootNS>.Views.People.Grid and <RootNS>.Views.People.List and, should then be located and displayed for <RootNS>.ViewModels.PeopleViewModel.

You typically then display the Views in something like a ContentControl, choosing the View you want to display by setting the cal:View.Context property. You'll either hard code the name, if the context isn't going to change in that particular control, or bind to a property which describes what state the ViewModel should be displayed as.

e.g.

<ContentControl cal:View.Model="{Binding Path=ActiveItem}" 
                cal:View.Context="List" />

See the Multiple Views over the Same ViewModel section.

like image 88
Chris Avatar answered Oct 01 '22 08:10

Chris


As far as I can tell from the documentation you are referring to, you should not use View in your view name. Name your view classes People.Grid and People.List instead.

like image 37
Anders Gustafsson Avatar answered Oct 01 '22 09:10

Anders Gustafsson