View.Model – ViewModel-First

Apr 16, 2011 at 5:00 PM

"Locates the view for the specified VM instance and injects it at the content site. Sets the VM to the Action.Target and the DataContext. Applies conventions to the view."

I realize the SL tab control is broken and have found a few posts on how to deal with it.  Basically, I'd like to have the ViewModel spin up for the selected tab item and the respective View injected into the content.  It would be nice to have lifecycle to so I'm not sure if I need to use a conductor or not.  I think the way in which I'm using cal:View.Model is wrong as its looking for the ViewModel as property of the main ViewModel.  Is there a way with cal:View.Model to specify a view model that will be looked up in the mef catalog?



            <sdk:TabItem FontSize="14"
                         cal:View.Model="{Binding ViewModel1}">
                <Grid />
            <sdk:TabItem FontSize="14"
                         cal:View.Model="{Binding ViewModel2}">
                <Grid />

Apr 16, 2011 at 7:48 PM
Edited Apr 16, 2011 at 7:48 PM

I recommend you to use a conductor, exposing the two VM instances as properties (in any case, you would need a VM for the view containing the tab). 
You can configure MEF to inject the two properties or have them passed in the constructor.
This way you also gain a full lifecycle management support. 

For the other approach, there is no builtin mechanism to pull from the container the VM and push the relative view with View.Model (as far as I know).
Bind.Model does support a string as a key to get a VM from the container, but it is intended to be used in View-first approach, so the view has to be already in place.

However, you can easily build an attached property (say ViewEx.ModelKey) with that behavior, if you need it:


 public static class ViewEx {
	public static DependencyProperty ModelKeyProperty =
                new PropertyMetadata(OnModelKeyChanged)
    public static string GetModelKey(DependencyObject d)
		return d.GetValue(ModelKeyProperty);
	public static void SetModelKey(DependencyObject d, string value)
		d.SetValue(ModelKeyProperty, value);
	private static void OnModelKeyChanged(DependencyObject targetLocation, DependencyPropertyChangedEventArgs args)
		var model = IoC.GetInstance(null, args.NewValue);
		View.SetModel(targetLocation, model);
Apr 17, 2011 at 12:58 AM

Thanks, I think I have it figured out and working.