Multi-View Support Query..

Topics: Getting Started, UI Architecture
Apr 2, 2012 at 12:54 PM

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 12:59 PM

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 1: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 2:01 PM
Edited Apr 2, 2012 at 2: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 2:12 PM
Edited Apr 2, 2012 at 2: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 2: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 4: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 4: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 5:09 PM

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