flq
flq

Reputation: 22849

Caliburn.Micro: Different "Targets" in XAML and how to get Views/Viewmodels into there

I'd still consider myself a beginner even though I could put CM to good use. I read this nice introduction on Screens and Conductors, etc. from Rob Eisenberg at codeplex. If I understood correctly a Conductor is itself a screen and may show screens.

However I don't see how to start in achieving something like this (very pseudo-code):

XAML

<Grid>
  <Left x:Name="Menu" />
  <Right x:Name="Content/ActiveItem" />
</Grid>

Now, how can I load two different screens, or maybe conductors, to be shown at those two locations?

I tried to understand from the "HelloScreens" sample, but sadly it's got so many dependencies I don't know how to get it to run. I can see that the ShellView seems to have two targettable areas, one is the usual "ActiveItem" the other is called "Dialogs" but a string search on "Dialogs" reveals nothing. There is too much magic going on there at this point in time.

Hence my question. What's the best strategy to finally get to grips how Views end up in the XAML and how to achieve something as shown above with Caliburn.micro?

Cheers

Upvotes: 4

Views: 1011

Answers (1)

devdigital
devdigital

Reputation: 34349

Caliburn comes with several types of conductors out of the box. One conductor with no collection of items (but an ActiveItem), and a couple of conductors with collections of items and an ActiveItem.

You could of course implement your own conductor too, but that doesn't sound necessary here. It sounds like you just want your ShellViewModel to be a conductor, perhaps one with a collection of items that it is conducting would make the most sense, so you can derive your ShellViewModel from Conductor<IScreen>.Collection.OneActive.

You menu doesn't need to conduct any items, it probably just needs a reference to the Items collection on your ShellViewModel. In your ShellViewModel constructor, you could instantiate each of the view models that will appear on the menu (probably using an abstract factory would be the nicest way) and then pass the Items reference to the MenuViewModel.

Each item that your ShellViewModel conducts can derive from Screen, so that they have the usual screen lifecycle (OnActivate, OnDeactivate etc). Your MenuViewModel isn't being conducted and doesn't require screen lifecycle, so can just derive from PropertyChangedBase.

With Caliburn.Micro, whenever you have a ContentControl on your view with the same name as a property on your view model whose value is itself a view model, then Caliburn.Micro will locate that view models view, and inject it into the ContentControl, and take care of the bindings too.

So your ShellViewModel could have a MainMenu property of type MenuViewModel, and your shell view would look something like:

<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="200" />
    <ColumnDefinition Width="*" />
  </Grid.ColumnDefinitions>
</Grid>

<ContentControl x:Name="MainMenu" Grid.Column="0" />
<ContentControl x:Name="ActiveItem" Grid.Column="1" />

Upvotes: 4

Related Questions