Transitioning from View First to VM First

Dec 15, 2010 at 3:24 PM

One of the benefits of having a view first approach was the ease of screen composition.

I've been searching for a way to do this, but go VM first instead of view first:

 <sdk:TabItem Header="View 1">
  <local:MyFirstView/> <!-- can't create the view here must figure out a way to bind to a VM or a conductor or something -->
 <sdk:TabItem Header="View 2"> 
  <local:MySecondView/><!-- can't create the view here must figure out a way to bind to a VM or a conductor or something -->

We have lots of places where multiple independant views are visible on the screen at the same time.  How do we create a shell that can contain multiple frames?

If I've missed an example somewhere, please forgive me.  I might not know what to look for.  Going view first makes this task easy...especially for us Blend people.


Dec 15, 2010 at 4:01 PM

To switch to VM first you would switch your user controls to ContentControls. Those ContentControls would each have a View.Model attached property with a binding pointing to the VM that should be injected at that site.

For a full databound composition approach, this is extremely easy with the WPF TabControl because it properly supports databinding and if using a Conductor.Collection.OneActive you can do the whole thing with one line of Xaml:

<TabControl x:Name="Items" />

But Silverlight's toolkit TabControl is broken. So, I tend to use a combination of ListBox (for tabs) and ContentControl for tab content, like so:

<ListBox x:Name="Items" DisplayMemberPath="DisplayName">

   ...use a horizontal stack for items panel...


<ContentControl x:Name="ActiveItem" />

This obviously requires more styling, but is also more flexible view-wise.

I don't really see a problem with your current implementation, unless you need the functionality of a conductor. If not, just keep it the way that it is. In fact, I did something exactly like this in a recent LOB app where I just needed the visual subdivision of Tabs, but not the behavior of a conductor.

If you need to bind different VMs to those UserControls, you can always use the Bind.Model attached property as well.

Dec 15, 2010 at 6:57 PM

I got you so far.  I'm trying to figure out the next step of moving over to caliburn....

How do I show multiple views on the screen at the same time when we don't know what views to show until we load in the viewmodels from MEF

<sdk:TabItem Header="View 1">
  <sdk:Frame Content="{Binding ChildConductor1.ActiveItem}"/> <!-- I can't do this. I used to bind to a UserControl created by this guy's ViewModel-->

I've tried to have a frame bind to a conductor's activeitem, but the frame was trying to show the ViewModel, not the view.

public class ParentViewModel
public Conductor<object> ChildConductor1 { get; set; }

public IChildViewModel1 ChildViewModel1 { get; set; }


Dec 15, 2010 at 8:31 PM


<sdk:TabItem Header="View 1">
  <ContentControl cal:View.Model="{Binding ChildConductor1.ActiveItem, Mode=TwoWay}"/>