Multi-View Support Query..

Topics: Getting Started, UI Architecture
Apr 2, 2012 at 11:54 AM

In the documentation for naming conventions there is this line:

Naming Convention for Multi-View Support

As mentioned in the Conventions section of the documentation, the framework was designed to handle a one-to-many relationship between ViewModel and View.

What I am finding hard to understand is when I am developing my program using ViewModel-First, how I can choose between the available view models? Where should I be choosing which View is loaded? Or is this really only meant for View-First development?

Apr 2, 2012 at 11:59 AM

The framework is able to resolve a view, given a view-model and a context, different view implementations can be bound to the same view-model, provided that the a different context is defined.

Dependening on your convention over view-location, it is just a matter of giving the proper namespace to your class, or explicitly setting the View.Context property.

See Multiple Views over the Same ViewModel section for more information.

Apr 2, 2012 at 12:53 PM

Ok so say I have a ViewModel:

CustomerUsageViewModel.cs

And two views:

CustomerUsageTableView.xaml

CustomerUsageGraphView.xaml

You're saying that I need to change the *.xaml files so that they have a unique context, ie.

CustomerUsage.Table.xaml - x:Class:="Application.CustomerUsage.Table" - cal:View.Context="{Binding Test}"
CustomerUsage.Graph.xaml - x:Class="Application.CustomerUsage.Graph" - cal:View.Context="{Binding Test}"

And then add a property called "Test" to the ViewModel, which I set to either "Table" or "Graph"?

But when I try that, the ViewModel complains that "Cannot find view for Application.CustomerUsageViewModel.". Am I missing a step?

 

Apr 2, 2012 at 1:01 PM
Edited Apr 2, 2012 at 1:01 PM

In CM, the default naming behavior for contextes applies this rule:

<Namepace>.<ClassName>[ViewModel] -> <Namespace>.<ClassName>.Detail

Where the class name is part of the namespace on the right side.

This means that your view classes should be named as

<Namespace>.CustomerUsage.Table.xaml
<Namespace>.CustomerUsage.Graph.xaml

with Table and Graph being the contextes.

Apr 2, 2012 at 1:12 PM
Edited Apr 2, 2012 at 1:13 PM

In reality my Views are contained within a "Views" folder in the project and named:

 

x:Class="Company.Product.Views.CustomerUsage.Table", etc.

 

My ViewModels are contained within a "ViewModels" folder and named:

 

Company.Product.ViewModels.CustomerUsageViewModel, etc

 

Is that not correct?

 

I know this sounds stupid, but how does the ViewModel know that it's looking for a View with a context, not just a "normal" view?

Apr 2, 2012 at 1:18 PM

Yes, as far as I can see, the views are named properly.

Note that you need to set the context in the containing ContentControl, and not in the view itself, I probably misread your previous post.

The part of your program that should be aware of the context, is not the view itself, but its container.

<UserControl>
      <ContentControl cal:View.Model="{Binding Path=Customer}"
                      cal:View.Context="{Binding Path=Customer.Mode}"/>
</UserControl>

Apr 2, 2012 at 3:55 PM

Ahhh fantastic, I can see the light at the end of the tunnel now! lol.. I can see various uses for this, however there's one that I'm a little unsure as to whether this is the "right" way to do it...

Say you have two users, a "basic" user and an "admin" user, each are displayed a slightly different UI dependant on their access rights. Could you create two Views, one for each user type? If so, assuming it's only the ViewModel/Model that knows which user is logged in, how does the VM go about setting the appropriate context in code rather than in XAML?

Apr 2, 2012 at 3:59 PM

If you want to keep the view-model the same (note that you could just create 2 view-models, where the advanced inherits, for example, from the basic one), you can just define a property over the view-model that acts as a context (it could be an enum), and set the property as needed upon login.

I would go with the separate view-models, tho.

Apr 2, 2012 at 4:09 PM

Again, brilliant response, hadn't even thought of doing it that way! :D