Caliburn Micro Part 6: Introduction to Screens and Conductors

Welcome to the next instalment of our simple Caliburn Micro tutorial series. This time we take a look at a powerful concept known as screens and conductors. If you have a look at the documentation on this topic, you’ll see there is quite a lot of content to cover. In this post I will just describe what screens and conductors actually are, and then take you step-by-step through building an application that uses screens and conductors in a very simple way.

So what are these things?

Most commonly, a screen is part of an application that goes through a life cycle. It can be activated, deactivated or closed. A good example of this which is used well in the documentation are the code editors in Visual Studio. A code editor is “activated” when a user opens a file to edit, it is “deactivated” when the user switches to a different tab, and it can be “closed” if the user closes the tab. An event is raised when the state of a screen changes so that external logic can be applied such as changing a toolbar based on the currently active screen. So far it sounds like screens are a special type of view-model, but this is not always the case. It is advised that screens are thought of more like roles, not view-models. Other usage scenarios are outside the scope of this tutorial series, so I will be sticking with using screens as view-models.

Conductors manage the life cycle state of one or more screens. They are responsible for activating, deactivating and closing the screens that it manages which will be done differently based on the scenario. Part of the closing operation includes querying the screen to see if it can close or not. If the screen is holding unsaved data for example, it would halt the closing operation so that unsaved work isn’t lost.

Screens and Conductors in Caliburn Micro

Caliburn Micro includes many interfaces related to screens and conductors. Each interface is for a very simple part of the whole system such as providing custom “can this screen close” logic or specifying whether or not a particular screen needs to be deactivated before the conductor activates a different screen. If you create your own custom screens or conductors, you can mix and match whichever interfaces you need so you only have to implement the functionality that you care about. Caliburn Micro does not expect screens or conductors to implement all the related interfaces; it will just work with whatever you give it. Fortunately, Caliburn Micro also includes some concrete classes that implement these interfaces. It is easy to extend these classes and override the bits of logic that you need to which is what I’ll be doing in this tutorial series. First I’d like to give a brief description of the three conductors that Caliburn Micro provides which are useful for different scenarios.

Conductor<T> – Manages a single screen at a time. Once it activates a new screen, any previous screen is deactivated, closed and forgotten by the conductor. This is used for very simple navigation/display scenarios.

Conductor<T>.Collection.OneActive – This one manages many screens at once and allows one screen to be active at one time, much like a tab control. When a screen is activated, the previously active screen is simply deactivated, it is not closed and remains under the management of the conductor. Screens can be explicitly closed to remove them. This type of conductor is also responsible for activating one of its screens if the active screen is closed. This has simple default logic that you can override if you need to.

Conductor<T>.Collection.AllActive – Very similar to the previous conductor, but allows multiple screens to be in the active state at once.

One common aspect of all the Caliburn Micro conductor implementations is that they extend the Screen class. This means the conductors can also be managed by other conductors which creates a very flexible model for building up applications in composable bits.

Now that you have the basic understanding of screens and conductors and what Caliburn Micro has to offer, let’s get straight into using them in a very simple demo.

Step 1: Getting started

I’ve designed this simple tutorial to continue directly from the Getting Started Tutorial. So if you haven’t done so already, follow through the steps of that tutorial which will only take a few minutes. By the end of today’s tutorial the application will display three buttons at the top of the window. Clicking a button will cause a conductor to activate and display a single screen in the area below the buttons. – Similar to the SimpleNavigation sample provided with Caliburn Micro.

Step 2: The conductor

Now lets change the AppViewModel to be a conductor. We will only be managing a single screen at a time, so we can use the very basic conductor. This is what AppViewModel will look like now:

public class AppViewModel : Conductor<object>
{
}

Note that deep down in the class hierarchy, Conductor extends PropertyChangedBase. This is why we can change what AppViewModel extends and still allow it to easily raise property change notifications which is an important part of an MVVM application.

Something to keep in mind: Now we have a conductor at the root of out application, and as mentioned above, Caliburn Micro conductors extend the Screen class. Screens require a conductor to activate them, so how will the root of our application be activated? The answer is that the Caliburn Micro Bootstrapper and WindowManager classes have support for displaying the root screens. So when building a Caliburn Micro application, make sure the root screens/conductors are managed by either the bootstrapper or a window manager.

Step 3: The screens

Now let’s add some screens to our application that the conductor will manage. For this tutorial, the screens will be view-models so make sure their names end with “ViewModel”. In the downloadable project you will see I’ve called them RedViewModel, GreenViewModel and BlueViewModel. These all extend the Screen class. For this tutorial we’ll be leaving these as empty classes, but I recommend seeing what methods you can override and play around with customizing their behaviors.

Next add a UserControl to each of these screens – remember to name them correctly using Caliburn Micro naming conventions (RedView, GreenView, BlueView). In each view I am simply displaying a colored TextBlock as in the following example:

<UserControl x:Class="CaliburnMicroApp_Navigation.RedView"
             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">
  <Grid>
    <TextBlock Text="Red" FontSize="48" FontWeight="Bold" Foreground="#FF463D" VerticalAlignment="Center" HorizontalAlignment="Center" />
  </Grid>
</UserControl>

Step 4: Interactivity

Now open AppView.xaml and add some buttons along the top of the application like this:

<DockPanel Width="300" Height="300" Background="LightBlue">
  <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" HorizontalAlignment="Center">
    <Button x:Name="ShowRedScreen" Content="Red" Width="50" />
    <Button x:Name="ShowGreenScreen" Content="Green" Width="50" Margin="12,0,0,0" />
    <Button x:Name="ShowBlueScreen" Content="Blue" Width="50" Margin="12,0,0,0" />
  </StackPanel>
</DockPanel>

In AppViewModel.cs (our conductor) the response of clicking a button will be to activate the appropriate screen. This is done by calling the ActivateItem method. Here is what AppViewModel.cs looks like now (remember that by naming the methods the same as the buttons, Caliburn Micro hooks them up for us):

public class AppViewModel : Conductor<object>
{
  public void ShowRedScreen()
  {
    ActivateItem(new RedViewModel());
  }
 
  public void ShowGreenScreen()
  {
    ActivateItem(new GreenViewModel());
  }
 
  public void ShowBlueScreen()
  {
    ActivateItem(new BlueViewModel());
  }
}

Step 5: displaying the active screen

Last of all, we need to display the currently active screen. This can be done by adding this mysterious-looking piece of code under the buttons:

<ContentControl x:Name="ActiveItem" />

This is another ingenious naming convention from Caliburn Micro. We have previously seen that by setting the name of a control, Caliburn Micro will automatically bind the main content/usage property of the control to the property on the view-model with the same name. In this case “ActiveItem” is a property on conductor which our AppViewModel extends. But the special thing about this scenario is that the ContentControl ends up displaying the appropriate view, NOT the view-model that the property actually returns. Once again showing that we can save a lot of time using Caliburn Micro.

Now run up the application and click the buttons to see the conductor do it’s thing:

Conductors

And that’s it for part 6 of our Caliburn Micro tutorial series. I hope this has been an easy introduction to understanding screens and conductors and using them in your applications. Although this was a simple demo, screens and conductors are a powerful MVVM way to manage life-cycle scenarios such as modal dialogs, navigation and dynamic tabs. For lots more info, check out the official documentation here. There is a lot to be read on this topic but it is well written.

Download the full Visual Studio solution for this tutorial from here.

Happy coding :)

Tagged as WPF

10 Responses to “Caliburn Micro Part 6: Introduction to Screens and Conductors”

  • […] Caliburn Micro Part 6: Introduction to Screens and Conductors (Jason Fauchelle) […]

  • […] Caliburn Micro Part 6: Introduction to Screens and Conductors (Mindscape Blog) […]

  • hi,

    am trying to become a .net programer,…last year am work with c# language…and also develop some asp.net web sites..after that..some simple windows form applications…then am going to work with WPF…am develop some simple wpf applications(database applications –>direct querry in button click..and other events)…………at this time my friend tells me, caliburn micro is good for xaml based applications…then am try to understand the caliburn micro…..at that time i saw u r website….working with u r tutorial..i got some basic ideas…especially i think..u r a brilliant in caliburn micro……

    My Questions are
    1 : “How to connect and work with sql sqerver in caliburn micro”–>connection string in viewmodel..???
    2 : “Where the database queries like insert,select…will be written ,…in view model..??
    3 : “How To connect a data-grid with sql datasource”—>

    Full..confusions……u just think…am a born baby in caliburn micro…am intrested with programming languages….

    <<>>

    …………………………………………Thanks in advance………………………. God Save You……………

  • Send any example Project…wpf with sql sqerver using caliburn micro

  • Hello Abdul

    Here is a blog post I wrote recently which may help you a little. The post is mostly about performance, but at the end of it you can download a sample that is a WPF application using Caliburn Micro that connects to a SQLite database. This may give you some ideas for your own projects. http://www.mindscapehq.com/blog/index.php/2013/10/08/building-wpf-applications/

    To work with a database, I recommend using an ORM which will do a lot of the work for you. In the application I mentioned, we used LightSpeed: http://www.mindscapehq.com/products/lightspeed

    When using LightSpeed, the connection string is setup in the app.config file. You are correct that database queries would be done in the view model. For your 3rd question, this would depend on what data-grid you are using, but you’d probably need to create some kind of adapter class that communicated between the data-grid and the database.

    Keep in mind that I am not a database expert, so you’ll want to find someone else to help you with more specific details.

  • how to create a application with tab type screen….i want to know more about Conductor.Collection.AllActive and Conductor.Collection.OneActive…………….any example

  • Hello Abdul

    You can read more about creating a tab type screen from the documentation here: http://caliburnmicro.codeplex.com/wikipage?title=Screens%2c%20Conductors%20and%20Composition&referringTitle=Documentation

    Look for the “Simple MDI” heading which talks about the Caliburn.Micro.SimpleMDI project.

  • Thank a lot :”>

  • By far the best explanation and demo of this topic.

  • I have used all of Jason’s tutorials. They are awesome! I sent these to others to help them learn MVVM and Caliburn. Keep up the good work!

  • Leave a Reply

Archives

Join our mailer

You should join our newsletter! Sent monthly:

Back to Top