Getting started

Topics: Getting Started
Aug 29, 2013 at 2:43 AM
I am really struggling to get to grips with even the simplest things using Caliburn Micro. I am looking at the Simple MDI example and trying to use two tabs of different views.

Here's my ShellView.xaml
<Window x:Class="WpfTestApp.Views.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:cal="http://www.caliburnproject.org"
        xmlns:local="clr-namespace:WpfTestApp.Views">
    <DockPanel>
       <TabControl Name="TabControl1">
            <TabItem Header="One">
                <local:OneView />
            </TabItem>
            <TabItem Header="Two">
                <local:TwoView />
            </TabItem>
        </TabControl>
    </DockPanel>
</Window>
The OneView and TwoView are identical
<UserControl x:Class="WpfTestApp.Views.OneView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:cal="http://www.caliburnproject.org"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="This is the view for "/>
        <TextBlock x:Name="DisplayName" />
        <TextBlock Text="." />
    </StackPanel>
</UserControl>
And the model
   public class OneViewModel : Screen
    {
        public OneViewModel()
        {
            DisplayName = "One";
        }
    }
When I run this, I see both Tabs but the DisplayName in the tab is not displayed. How do I get this to display?

Is there a way to build the tab control items dynamically using composition?

Regards
Alan
Aug 31, 2013 at 9:09 PM
Edited Aug 31, 2013 at 9:11 PM
there are examples of using MEF or your favorite IoC to do that dynamically. But down to what you have.. you are basically mixing 2 variations of MVVM, view-first and viewmodel first, the later which Caliburn.Micro exceeds at. Choose one variation and run with it..

How do you have your ShellViewModel configured?

MEF option will require some wire up to get it to get your "Screens" to dynamically be populated and your shellviewmodel will have some requirements to allow either all screens active or a single screen at any given time.
Sep 1, 2013 at 11:16 PM
My ShellViewModel has the following code
    [Export(typeof(IScreen))]
    public class ShellViewModel : Conductor<IScreen>.Collection.OneActive
    {
        public ShellViewModel()
        {
            Items.Add(new OneViewModel());
            Items.Add(new TwoViewModel());

            ActivateItem(Items[0]);
        }
    }
I am adding my ViewModels statically since they are being added dynamically and this seems to work but I still don't follow why Items is not auto-populated. I am using the classic MEF Bootstrapper as per the Caliburn Micro documentation inheriting from Bootstrapper<IScreen>.

Regards
Alan
Sep 3, 2013 at 12:44 AM
Edited Sep 3, 2013 at 12:51 AM
Like I said previously you were mixing two MVVM disciplines and I think it might have even confused you a little, because you have to specifically tell it to populate the Items, it will not do it automatically... then when everything is setup correctly you will see Tabs

something like this...

public class ShellViewModel : Conductor<IScreen>.Collection.OneActive{
 [ImportingConstructor]

 public ShellViewModel([ImportMany]IEnumerable<IScreen> Screens){

          DisplayName = "CM - Example";
          Items.AddRange(Screens);

 }

 protected override void OnActivate(){
        ActivateItem(Items[0]);
 }
}

then with your tabcontrol in the ShellView.xaml

<TabControl x:Name="Items" />

Also your tab text (header) will be bound automagically due to the conventions, CM magic...

http://sdrv.ms/15zbZ78 a sample for some clarity