Goodbye Funambol and the MVP community, welcome Blue Badge

It’s been a while since my last blog post: unfortunately, I’ve been very busy in the latest month to deliver my new book about Universal Windows apps development, that will be published as a free e-book by Syncfusion in the upcoming months. Moreover, a big professional change happened in my life too, that you should already know if you follow me on Twitter: in the beginning of October I’ve resigned from my previous company, Funambol, and since 2 weeks I’ve joined Microsoft as a Support Engineer, focused on supporting Windows Phone and Windows Store apps developers. Consequently, I’m no longer a member of the MVP community: it’s the “price to pay” to join Microsoft, since the MVP award is given only to independent developers, so you can’t be a Microsoft employee and a MVP at the same time. However, even if it’s a displeasure not to be party anymore of such a great community, I’m really excited about my new position: now I have the chance to do, as a job, what I like most, which is supporting developers and helping them to deliver great Windows Phone and Windows Store applications. However, community played an important role in the latest years, both in my professional and personal life: being not a MVP anymore doesn’t mean that I will stop to support communities, so I will continue to write on my blog, to speak at conferences and to answer your questions.

I promise, too, to start writing more on my blog Smile

WP_20141121_08_55_27_Pro 1

Posted in Developer's life | Tagged , | 3 Comments

Using Caliburn Micro with Universal Windows app – Design time data

One of the most powerful features in XAML is design time data support. Let’s say that you have an application that displays some news retrieved from a RSS feed using a ListView or a GridView control. If you try to edit the visual layout of your application using Blend or the Visual Studio designer, you won’t be able to get a preview of the final result: since data is retrieved from a remote service, the ListView will look empty, since the designer isn’t able to load the real data. This scenario makes hard for a designer to have a real preview of the final result or to edit some elements (like the ItemTemplate of the ListView).

Design data is the solution to this problem: it’s basically a way to create fake data, that is loaded only when the View is displayed in Blend or in the Visual Studio designer. Let’s see how to manage this scenario using Caliburn Micro.

The sample app: a simple news reader

As a sample, we’re going to develop a simple news reader, that will read and parse the RSS feed of this blog. The real application will display the real posts from the blog, while the designer will display some fake posts, just to give to designer an idea of the content that will displayed in the page. First, let’s start to set up the real application, using the conventions we’ve learned in the previous posts. The application will have just one View, that will display a list of posts using a ListView control.

First, let’s define a simple class that will map some of the information about the post that we want to display in the page:

public class FeedItem
{
    public string Title { get; set; }
    public DateTimeOffset PublishDate { get; set; }
    public string Description { get; set; }
}

Then, we need to download the RSS feed from the web and convert the XML into a list of FeedItem objects. For this purpose, we’re going to create a separate class, that will take care of processing the RSS feed: we’re going to define a method that will take, as input, the URL of the RSS feed and will return, as output, a collection of FeedItem objects. Here is how the interface of the class looks like:

public interface IFeedService
{
    Task<IEnumerable<FeedItem>> GetNews(string feedUrl);
}

To implement it, we’re going to use one of the new 8.1 APIs, called SyndicationClient: it’s a special HttpClient implementation that is able to download the RSS feed and to automatically parse it, so that you can work with classes and objects instead of raw XML. Here is the implementation:

public class FeedService: IFeedService
{
    public async Task<IEnumerable<FeedItem>> GetNews(string feedUrl)
    {
        SyndicationClient client = new SyndicationClient();
        SyndicationFeed feed = await client.RetrieveFeedAsync(new Uri(feedUrl, UriKind.Absolute));
        List<FeedItem> feedItems = feed.Items.Select(x => new FeedItem
        {
            Title = x.Title.Text,
            Description = x.Summary.Text,
            PublishDate = x.PublishedDate
        }).ToList();

        return feedItems;
    }
}

We use the RetrieveFeedAsync() method, which takes in input the URL of the RSS feed (which is passed as parameter of the GetNews() method), and it will give you in return a SyndicationFeed object, which stores all the information about the feed. What’s interesting for us is the Items collection, which contains all the news that are included in the feed (in our case, the list of all the posts published in this blog). Using LINQ, we convert it into a collection of FeedItem objects, by grabbing the title, the description and the published date of the post.

Now we need to use this class in the ViewModel that is connected to our page. The easiest way would be to simply create a new instance of the FeedService class and to call the the GetNews() method, like in the following sample:

public class MainPageViewModel : Screen
{

    public MainPageViewModel()
    {
    }

    private List<FeedItem> _news;

    public List<FeedItem> News
    {
        get { return _news; }
        set
        {
            _news = value;
            NotifyOfPropertyChange(() => News);
        }
    }

    protected override async void OnActivate()
    {
        IFeedService feedService = new FeedService();
        IEnumerable<FeedItem> items = await feedService.GetNews("http://feeds.feedburner.com/qmatteoq_eng");
        News = items.ToList();
    }
}

However, this approach has some cons. Let’s say that, due to some changes in the requirements, you need to swap the FeedService() class with another implementation, by keeping the IFeedService interface as a base ground. With this approach, you would have to go in every ViewModel in which you’re using the FeedService class and replace the implementation. But wait, there’s a better way to do that: using the dependency injection container provided by Caliburn Micro!

Let’s move to the App.xaml.cs file and, in the Configure() method, let’s register the FeedService, like we did for the different ViewModels:

protected override void Configure()
{
    container = new WinRTContainer();

    container.RegisterWinRTServices();

    container.PerRequest<MainPageViewModel>();
    container.PerRequest<IFeedService, FeedService>();
}

The only difference is that, this time, since we have an interface that describes our class, we use another approach: instead of registering just the class (by calling the PerRequest<T>() method), we bind the interface with the concrete implementation, by using the PerRequest<T,Y>() method. Now, to get a reference to the FeedService class in our ViewModel, we simply need to add a new parameter in the constructor, which type is IFeedService, like in the following sample:

public class MainPageViewModel : Screen
{
    private readonly IFeedService _feedService;

    public MainPageViewModel(IFeedService feedService)
    {
        _feedService = feedService;
    }

    private List<FeedItem> _news;

    public List<FeedItem> News
    {
        get { return _news; }
        set
        {
            _news = value;
            NotifyOfPropertyChange(() => News);
        }
    }

    protected override async void OnActivate()
    {
        IEnumerable<FeedItem> items = await _feedService.GetNews("http://feeds.feedburner.com/qmatteoq_eng");
        News = items.ToList();
    }
}

We’ve simply added a parameter in the constructor which type is IFeedService: the dependency injection container will take care of resolving the parameter at runtime, by injecting the real implementation we’ve defined in the App class (in our case, FeedService). This way, if we need to use a different implementation of the IFeedService class, we simpy have to go back to the App class and change the Configure() method we’ve previously defined, instead of having to change the code in every ViewModel that needs to use this class. Now we can simply define our View using a ListView control, to display the posts retireved by the FeedService:

<ListView ItemsSource="{Binding Path=News}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Path=Title}" Style="{StaticResource TitleTextBlockStyle}" />
                <TextBlock Text="{Binding Path=PublishDate}" Style="{StaticResource BodyTextBlockStyle}"></TextBlock>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Now if you run the app (it doesn’t matter if the Windows 8.1 or the Windows Phone 8.1 version) you should see the lists of posts recently published on this blog, downloaded from the following RSS feed: http://feeds.feedburner.com/qmatteoq_eng

image

Using design data

If you try to open your project in Blend or you enable the Visual Studio designer, you’ll notice that the page will be empty: the real FeedService isn’t executed during design time, so you don’t get a chance to see the list of posts. The purpose of our work will be to display a list of fake posts, in case the View is displayed inside the designer.

One thing you should have noticed, while working with Caliburn, is that you don’t get Intellisense while you’re dealing with binding, unlike when you work with other toolkits like MVVM Lights. This happens because you’re not explicitly setting the DataContext of the page: it’s automatically resolved at runtime, by using the specfic Caliburn naming convention. The result is that, when you’re writing the XAML, the View doesn’t know which is the ViewModel that is connected to it. This is a consequence of the design data requirement: we need to tell to the View which is the connected ViewModel, so that it can enable Intellisense and that it can provide design data for us.

Here is how to do it:

<Page
    x:Class="DesignData.Views.MainPageView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:DesignData"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:micro="using:Caliburn.Micro"
    xmlns:viewModels="using:DesignData.ViewModels"
    mc:Ignorable="d"
    d:DataContext="{d:DesignInstance Type=viewModels:MainPageViewModel, IsDesignTimeCreatable=True}"
    micro:Bind.AtDesignTime="True"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <ListView ItemsSource="{Binding Path=News}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Path=Title}" Style="{StaticResource TitleTextBlockStyle}" />
                        <TextBlock Text="{Binding Path=PublishDate}" Style="{StaticResource BodyTextBlockStyle}"></TextBlock>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>

First we’ve defined which is the DataContext of the page, but we did it in a different way, by adding the prefix d: this way, we’re telling to the XAML compiler that this value should be used only at design time, while at runtime the application will continue to use the standard DataContext (in our case, the ViewModel assigned by Caliburn). With this definition, basically we’re manually defining what Caliburn automatically does at runtime: we’re telling to the current View that the DataContext class to use is called MainPageViewModel and that supports design time data.

Then, we need to use a special Caliburn attached property, that is able to perform the binding for us at design timed: it’s called Bind.AtDesignTime and its value has to be set to True. Please note that, to get this code working, we need to define two XAML namespaces: the first one (called viewModels in the sample) which points to the project’s folder that contains all our ViewModels (in our case, using:DesignData.ViewModels, where DesignData is the name of the project); the second one (called micro in the sample) it’s the default Caliburn one, which is using:Caliburn.Micro.

After this setup, one thing you’ll immediately notice is that you’ll get Intellisense up and running: if you try to setup a new binding with a control, Visual Studio will propose you one of the properties that have been declared in the ViewModel.

Now it’s time to define the design time data: one important thing to highlight is that this feature, to work properly in Caliburn, requires a parameterless constructor. In our case, it will be different than the standard one (which, instead, contains a parameter which type is IFeedService): in this empty constructor we’re going to set up the fake data, by filling the News collection (the one displayed in the ListView control) with a list of fake posts, like in the following sample.

public class MainPageViewModel : Screen
{
    private readonly IFeedService _feedService;

    public MainPageViewModel(IFeedService feedService)
    {
        _feedService = feedService;
    }

    public MainPageViewModel()
    {
        if (Execute.InDesignMode)
        {
            News = new List<FeedItem>
            {
                new FeedItem
                {
                    Title = "First news",
                    Description = "First news",
                    PublishDate = new DateTimeOffset(DateTime.Now)
                },
                new FeedItem
                {
                    Title = "Second news",
                    Description = "Second news",
                    PublishDate = new DateTimeOffset(DateTime.Now)
                },
                new FeedItem
                {
                    Title = "Third news",
                    Description = "Third news",
                    PublishDate = new DateTimeOffset(DateTime.Now)
                }
            };
        }
    }

    private List<FeedItem> _news;

    public List<FeedItem> News
    {
        get { return _news; }
        set
        {
            _news = value;
            NotifyOfPropertyChange(() => News);
        }
    }

    protected override async void OnActivate()
    {
        IEnumerable<FeedItem> items = await _feedService.GetNews("http://feeds.feedburner.com/qmatteoq_eng");
        News = items.ToList();
    }
}

As you can see, the main code of the ViewModel is the same: we have one constructor, that takes care of initializing the IFeedService object; we have a property called News, which contains a list of FeedItem objects; in the OnActivate() method (that is invoked when the view is displayed) we use the FeedService class to retrieve the list of posts and to display it in the View.

The difference is that now we have a constructor without parameters, in which we initialize a list of fake posts: we manually create some FeedItem objects and we add them to the News collection. Of course, we want to do that only if the View is displayed in the designer: we don’t want to display fake data when the app is running on the phone. For this purpose, we can use a Caliburn class called Execute, which provides some useful properties and methods: for our scenario we can use a property called InDesignMode, which is a simple boolean that is set to true in case the View is displayed inside the designer. We’re goint to add fake data to the News collection only if the value of this property is set to true.

Now, build your project and try to open the designer: you’ll notice that the View won’t be empty anymore, but it will display the fake data we’ve provided.

image

Wrapping up

As usual, I’ve commited all the samples described in this post in my GitHub project (https://github.com/qmatteoq/CaliburnMicro-UniversalApp-Demo), inside the folder called DesignData. Have fun!

Posted in Universal Apps, Windows 8, Windows Phone | Tagged , , | 4 Comments

Using Caliburn Micro with Universal Windows app – Messages

When you’re developing an application using the MVVM pattern, one of the most common needs is to create a communication channel between two ViewModels or a ViewModel and a View: you need to exchange some data between the two actors, but you don’t have an easy way because everything is decoupled.

Messages are the perfect solution for such scenarios: they’re basically objects, that a class (like a ViewModel) can send using a special messenger; any other class can subscribe to receive such kind of messages and perform an operation when it happens. With this approach, we are able to maintain the fundamental concept of MVVM, which is “separation of concerns”. When a class sends a message, it doesn’t know who will be the receiver: it’s the class that wants to receive the message that needs to act and prepare itself to receive messages.

In Caliburn Micro, this scenario is achieved using one of the built-in services, called EventAggregator: it’s our postman and we’re going to use it to publish and to receive messages.

Let’s see how it works and how to use it in a Universal Windows app.

Sending a message

As a sample scenario, we’re going to develop a simple application with two pages: a main page and a detail page. The detail page will offer a button that will send a message containing some text; the main page will subscribe itself to receive this message and it will display the text on the screen, using a TextBlock control.

I won’t go into the details needed to setup the application and to connect the ViewModel’s properties and actions to the UI: you can see my previous posts, where I explained the basic concepts of a Caliburn Micro application.

The first step to use the EventAggregator is to add a reference to it in our ViewModel: in the same way we did in the previous post for the NavigationService, we need to add a parameter in the constructor of the ViewModel’s class, which type will be IEventAggregator.

public class DetailPageViewModel: Screen
{
    private readonly IEventAggregator _eventAggregator;

    public DetailPageViewModel(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
    }
}

Now that we have a reference to the EventAggregator class, we can manage the button’s click: we’re going to define a method in the ViewModel, that will be invoked when the button is clicked. The purpose of this method is to send a message:

public async void SendMessage()
{
    string message = "This is a simple message";
    await _eventAggregator.PublishOnUIThreadAsync(message);
}

In this sample the message is simply a text: we send a string object by passing it as parameter of the method PublishOnUIThreadAsync() offered by the EventAggregator class. There are multiple ways to send a message: we’ll deal with them later. For the moment, it’s important to know that the PublishOnUIThreadAsync() method simply takes the object passed as parameter and sends it as a message on the UI thread. This means that the receiver class will receive it on the same thread that manages the user interface of the application: it’s perfect for our scenario, since we’re simply going to display the text on the UI.

Receiving a message

There are two steps to register a class to receive a message: the first one requires to use, again, the EventAggregator class. As a consequence, you’ll need to add an IEventAggregator parameter also in the receiver’s ViewModel constructor. The difference is that, this time, we’re going to call the Subscribe() method, that will communicate to our postman that the current class wants to receive messages.

public class MainPageViewModel: Screen
{
    public MainPageViewModel(IEventAggregator eventAggregator)
    {
        eventAggregator.Subscribe(this);
    }
}

As a parameter of the Subscribe() method you need to pass which class is going to subscribe to receive messages: since, in this case, it’s the ViewModel itself, we simply pass the value this, that is a reference to the current class.

The second step is to implement the IHandle<T> interface, where T is the type of message we want to receive: by doing so, you’ll be forced to implemented the Handle() method, which will receive as input the message.

public class MainPageViewModel: Screen, IHandle<string>
{
    private string _text;

    public string Text
    {
        get { return _text; }
        set
        {
            _text = value;
            NotifyOfPropertyChange(() => Text);
        }
    }

    public MainPageViewModel(IEventAggregator eventAggregator)
    {
        eventAggregator.Subscribe(this);
    }

    public void Handle(string message)
    {
        Text = message;
    }
}

Here is a complete sample of the MainPageViewModel class: first, we’ve implemented the IHandle<string> interface, since we want to receive the message sent by the DetailViewModel class, which is a string. Then, we’ve created a method called Handle(), which receives as parameter a string, since it’s the type of message we expect: now we are free to manage the message as we prefer, according to our needs. In the sample, we simply take the string and we assign it to a property called Text, which is connected to a TextBlock control in the View.

If we try this simple application, we’ll see that, if we tap on the button to send the message that we’ve placed in the detail page and then we go back to the main page, the text stored in the message will be successfully displayed on the screen.

Sending and receiving complex messages

In the previous sample we’ve simply sent a string as a message. However, there are situations when using a base type can be too generic: for example, we could have multiple ViewModel registered to receive string messages, but we want that a particular message is received only by a specific ViewModel.

In this case, the solution is easy: the EventAggregator can send not only basic types as messages, but also complex objects. Let’s try to implement the same scenario, but with a different approach: instead of sending a simple string, we’re going to send an object that will store a string.

First, we need to add a new class in our application, that can act as a message. We’re going to call it SimpleMessage:

public class SimpleMessage
{
    public string Text { get; private set; }

    public SimpleMessage(string text)
    {
        Text = text;
    }
}

It’s a simple class, which exposes a string parameter called Text, which is initialized using the constructor. The next step is to send the message, using the same approach we’ve seen before with the EventAggregator class and the PublishOnUIThreadAsync() method: the only difference is that, this time, instead of passing as parametere a simple string, we’re going to send a SimpleMessage object.

public async void SendComplexMessage()
{
    SimpleMessage message = new SimpleMessage("This is a complex message");
    await _eventAggregator.PublishOnUIThreadAsync(message);
}

Now, in the MainPageViewModel, we need to subscribe to receive the SimpleMessage by simply implementing the IHandle<T> interface in the proper way, like in the following sample:

public class MainPageViewModel: Screen, IHandle<SimpleMessage>
{
    private string _text;

    public string Text
    {
        get { return _text; }
        set
        {
            _text = value;
            NotifyOfPropertyChange(() => Text);
        }
    }

    public MainPageViewModel(IEventAggregator eventAggregator)
    {
        _navigationService = navigationService;

        eventAggregator.Subscribe(this);
    }

    public void Handle(SimpleMessage message)
    {
        Text = message.Text;
    }
}

Nothing special to mention: it’s the same approach we’ve used before, the only difference is that this time the Handle() method will receive a real object (which type is SimpleMessage) instead of a simple type.

Sending and receiving messages to the code behind

Another common scenario is the communication between a ViewModel and a View: there are, in fact, certain operations that require direct access to the controls, like starting an animation or invoking a method that is exposed only in code behind. A way to solve this scenarios is using behavior, but sometimes they can be complex to define: sending messages is much easier.

Sending and receiving messages in the code behind is the same we’ve seen before with ViewModels: we send messages using the EventAggregator class and we receive them by implementing the IHandle<T> interface. The only difference is that, in the code behind, we can’t add an IEventAggregator paramter to the constructor: dependency injection works fine only for ViewModels. The solution is to manually interact with the Caliburn container, to explicity ask for an EventAggregator object: to achieve this result, we first need to do a change in the App class since, by default, the container is declared as a private variable, so we can’t use it in another class.

public sealed partial class App
{
   public WinRTContainer container { get; private set; }

   public App()
   {
       InitializeComponent();
   }
}

We’ve simply changed the container’s type from private to public and we’ve turned it into a property. Now, from every class, we can access to the container in the following way:

WinRTContainer container = (Application.Current as App).container;

To explicity ask for an instance of a class registred in the container, we need to use the GetInstance<T> method. Let’s see that we want to receive the SimpleMessage object we’ve sent before in the code behind of the MainPage View. Here is how we can do it:

public sealed partial class MainPageView : Page, IHandle<SimpleMessage>
{
    public MainPageView()
    {
        this.InitializeComponent();

        this.NavigationCacheMode = NavigationCacheMode.Required;

        WinRTContainer container = (Application.Current as App).container;

        IEventAggregator eventAggregator = container.GetInstance<IEventAggregator>();

        eventAggregator.Subscribe(this);
    }

    public void Handle(SimpleMessage message)
    {
        MessageContent.Text = message.Text;
    }
}

As you can see, there aren’t big differences with the previous approach: the class implements the IHandle<SimpleMessage> interface and, as a consequence, it defines the Handle() method which receives, as parameter, a SimpleMessage object. The only difference is that we set up the EventAggregator in another way: after we’ve obtained a reference to the WinRTContainer object, we ask for the EventAggregator instance registered in the container by calling the GetInstance<IEventAggregator>()  method. Then, we proceed as usual, by calling the Subscribe() method passing this as parameter, since we want the actual code behind class to be able to receive messages.

Managing messages in a background thread

One of the new features added in Caliburn Micro 2.0 is the support to send messages in a background thread. This scenario is useful if the receiver class needs to perform intensive operation when the message is received: to avoid impacting on the UI, we can handle the message in a separate thread. Sending a message in a background thread is really easy: just use the PublishOnBackgroundThread() method offered by the EventAggregator class, like in the following sample:

public void SendMessageInBackground()
{
    SimpleMessageInBackground message = new SimpleMessageInBackground("This is a message handled in a background thread");
    _eventAggregator.PublishOnBackgroundThread(message);
}

 

Then, in the receiver class, we’ll handle it in the same way we did in the previous samples: we implement the IHandle<T> interface and we manage the Handle() method in the class. The only difference is that, this time, the Handle() method will be executed on the background thread: we need to remember that, if we need to interact with the View (for example, by changing a control’s property) we need to use the Dispatcher, which takes care of redirecting the operation to the UI thread; otherwise, we will get a cross-thread access exception.

Take a look at the following sample:

public sealed partial class MainPageView : Page, IHandle<SimpleMessageInBackground>
{
    public MainPageView()
    {
        this.InitializeComponent();

        this.NavigationCacheMode = NavigationCacheMode.Required;

        WinRTContainer container = (Application.Current as App).container;

        IEventAggregator eventAggregator = container.GetInstance<IEventAggregator>();

        eventAggregator.Subscribe(this);
    }

    public void Handle(SimpleMessageInBackground message)
    {
        Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            MessageContent.Text = message.Text;
        });
    }
}

This sample is similar to the previous one: in a code behind class we register to receive a message which type is SimpleMessageInBackground. The final result is the same: we display the content of the message in a TextBlock control called MessageContent. The difference, this time, is that we do it using the RunAsync() method of the Dispatcher class, since we’re interacting with a control in the XAML but the message is being handled in a background thread.

That’s all!

In this post we’ve covered all the basic concepts about sending and receiving messages in a MVVM application built with Caliburn Micro 2.0. The last week I’ve decided to publish all the samples connected to this series of post about Caliburn Micro and Universal Windows app on GitHub: the repository is available on https://github.com/qmatteoq/CaliburnMicro-UniversalApp-Demo. You’ll find in the solution, together will all the samples of the previous posts, also a new one about messages.

Posted in Windows 8, Windows Phone | Tagged , , | 4 Comments

Porting a Windows Phone 8.0 application to Caliburn Micro 2.0

In my everyday job at Funambol I work on an application called OneMediaHub, which is the Windows Phone client for the cloud services offered by the company. The application is built using the MVVM pattern and Caliburn Micro as a framework. Now that the development cycle of the new version of the client is completed, one of my goal before starting working on the new features for the next version is to upgrade Caliburn Micro from the previous version (1.5.3) to the most recent one (2.0).

However, as I discovered by my self, the procedure isn’t so straight forward: Caliburn Micro is a big improvemenet compared to the previous version, but it also includes many breaking changes. In this post I’ll detail the most important ones I had to face during the migration.

Changes in bootstrapper

The boostrapper is the base class that replaces the App one and that takes care of initializing the app, among all the Caliburn services and conventions.

There are two important changes in the boostrapper with Caliburn Micro 2.0:

  • In the previous release, the bootstrapper’s class had to inherit from the PhoneBootstrapper one. Now, instead, the base class has been renamed to PhoneBootstrapperBase.
  • Now, in the constructor of the bootstrapper’s class, you need to call the Initialize() method, while in the previous version it wasn’t required.

Here is a full working initialization of the bootstrapper for Caliburn Micro 2.0:

public class CaliburnBootStrapper : PhoneBootstrapperBase
{
    public OneMediaHubBootStrapper()
    {
        this.Initialize();
    }
}

Thanks to Matteo Tumiat that pointed me in the right direction: without calling the Initialize() method, the app was stuck in the loading phase, without any warning or exception.

Changes in EventAggregator

EventAggregator is the class used to manage messages (which are, in the end, simple objects) that can be sent and received from different classes (like two ViewModels or a ViewModel and a View). This approach helps to create a communication channel between different classes while keeping alive, at the same time, the fundamental MVVM concept of “separation of concerns”. In fact, when a class sends a message, it doesn’t know who’s going to receive it: it’s the receiver class that will simply register itself to handle specific kind of messages.

To send a message in Caliburn Micro 1.5 we used the Publish() method of the IEventAggregator class, that simply dispatched the object using the UI thread. In Caliburn Micro 2.0 this method doesn’t’ exists anymore and it’s been replaced with multiple methods, that support a greater number of scenarios, like sending messages on a background thread, or using the UI thread but in an asynchronous way.

If you want to replace the Publish() method without changing the old behavior (so the message is sent in a synchronous way on the UI thread), you just need to use the new PublishOnUIThread() method.

Otherwise, if you want to improve performances and avoid to overload the UI thread, you can use the new asynchronous version, which is PublishOnUIThreadAsync(): however, by doing this, you’ll need a bit more work to complete the porting; since the metod is asynchronous , you’ll have to add as prefix the await keyword and mark the container method with the async one. But, most of all, you’ll have to verify that you’re correctly managing the asynchronous pattern: for instance, if your method that sends the message is marked as void and it’s not an event handler, you should change it so that it returns a Task, so that it can be correctly awaited by the caller.

private async Task SendMessage()
{
  
    await eventAggregator.PublishOnUIThreadAsync(new SimpleMessage());
  
}

There’s also another useful new method offered by the IEventAggregator class, which is called PublishOnBackgroundThread(): by using it, the Handle() method that will receive it will be executed in a background thread instead of the UI thread. It’s useful when the receiver class needs to perform many CPU consuming tasks when a message is received.

New namespace for the Message class

In my application I found myself multiple times using the Message.Attach attached property, which can be useful to manage in a ViewModel events that are raised by controls in the UI. In the previous Caliburn Micro version, the Message class was define inside the Caliburn.Micro assemply. It means that, to use it, you had added the following namespace in the XAML definition:

xmlns:micro="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro

Now the assembly that contains the Message class is changed to Caliburn.Micro.Platform: as a consequence, you’ll have to change all your XAML namespaces definition to

xmlns:micro="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro.Platform"

Managing the application bar

To manage the application bar in a Caliburn way I’ve used in my project a third party component made by Kamran Ayub, called CaliburnBindableAppBar. I’ve talked abut it in details in the following blog post. The problem comes if, like me, you’ve installed the component using NuGet: the available version, in fact, it’s compiled against Caliburn Micro 1.5 and it won’t work if you upgrade your project to Caliburn Micro 2.0. However, the developer has already updated the project: on GitHub you can see that the component already supports Caliburn Micro 2.0, as stated in the changelog. I’ve already contacted the developer and he promised me that he’s going to update the package on NuGet soon; however, if you need to use the updated application bar right now, the solution is simple: just download the project from GitHub and compile it by yourself or add it to your solution.

That’s all!

If you had a similar experience and you found other changes that are worthes to be mentioned, feel free to leave a comment!

Posted in Windows 8, Windows Phone | Tagged , , | Leave a comment

Using Caliburn Micro with Universal Windows app – Navigation

Let’s continue our journey with Caliburn Micro and Universal Windows app. After talking about the project setup and binding and actions, let’s see how to manage navigation in a Windows and Windows Phone 8.1 app.

The NavigationService

Managing navigation is one of the challengers offered by the MVVM pattern: the Windows Runtime offers a static class called Frame, which exposes the methods needed to perform the navigation. This class is available only in the code behind, since it’s inherited from the Page class, which is the base class from which every application’s page inherits from. Since the ViewModels don’t inherit from the Page class, you won’t be able to directly access to the Frame class. Here comes the NavigationService class, which is a wrapper that can be used to perform navigation duties inside a ViewModel. Using it is really simple: since it’s one of the services that is embedded in Caliburn Micro, it’s automatically registered during the startup (do you remember the RegisterWinRTServices() method that is called in the Configure() method defined in th App.xaml.cs file?).

To get access to the NavigationService, you simply need to add a parameter of type INavigationService to the ViewModel constructor: the container will take care of injecting the concrete implementation of the service at runtime. Here is a sample of a ViewModel that registers the NavigationService:

public sealed class MainPageViewModel: Screen
{
    private readonly INavigationService _navigationService;

    public MainPageViewModel(INavigationService navigationService)
    {
        this._navigationService = navigationService;
    }
}

Now you’ll be able to use the NavigationService across the ViewModel: for example, you can use it in a method that is triggered when a button is clicked. One of the nice things of the NavigationService class is that supports a ViewModel-First approach, which is very useful when you work with the MVVM: you can specify, instead of the page where to redirect the user, the ViewModel that is associated to the page. Caliburn Micro will take care of resolving the correct page and it will perform the navigation. This goal is achieved using the method NavigateToViewModel<T>(), where T is the type of ViewModel where we want to redirect the user.

Here is a sample:

public void GoToDetail()
{
    _navigationService.NavigateToViewModel<DetailPageViewModel>();
}

Managing parameters

One of the most interesting changes included in the Windows Runtime is that navigation isn’t based anymore on uris like in Silverlight: as a consequence, you are able to pass as navigation’s parameters also complex objects, while in Windows Phone 8.0 you were forced to pass only plain data (like texts or numbers). Caliburn Micro 2.0 supports this scenario, simply by accepting a parameter in the NavigateToViewModel<T>() method. Let’s use the same sample we’ve seen in the previous post: we’re going to display a list of movies using a ListView control. When the user taps on one of them, we’re going to use the ItemClick event to redirect him on the detail page.

public void GoToDetail(Movie movie)
{
    _navigationService.NavigateToViewModel<DetailPageViewModel>(movie);
}

We’ve simply added the object received by the method GoToDetail() as parameter to the NavigateToViewModel<T>() method. Now we have another problem: how to get the parameter in the destination ViewModel? In an application developed without MVVM, we would have used the OnNavigatedTo() method defined in the code behind: the parameter returned by the method contains a property, called Parameter, with the object that has been sent by the source page. But, again, this is a scenario that can be satisfied because the code behind class inherits from the Page class: we can’t say the same for the ViewModel class.

Caliburn Micro uses a naming convention to manage this scenario: you just have to define, in the destination ViewModel, a property called Parameter, which type is the same of the object you’ve passed to the NavigateToViewModel<T>() method. Since, in the previous example, we passed a Movie object, here is how we can setup the DetailPageViewModel class:

public class DetailPageViewModel: Screen
{
    public Movie Parameter { get; set; }

    private string title;

    public string Title
    {
        get { return title; }
        set
        {
            title = value;
            NotifyOfPropertyChange(() => Title);
        }
    }

    protected override void OnActivate()
    {
        Title = Parameter.Title;
    }
}

As you can see, in the DetailPageViewModel class we’ve added a new public property called Parameter, which type is Movie. This way, we’ll be able to access to the Movie object sent by the main page: in this sample, we’re going to display the title of the movie in the page , by assigning it to the Title property. The operation is performed in the OnActivate() method, which is triggered when the page is displayed: it’s one of the navigation events that is offered by the Screen class which, as you may have noticed, is the one all the ViewModels are inheriting from. With this method, we are able to recreate the OnNavigatedTo() event inside the ViewModel.

Managing the back button

One of the biggest differences between Windows Phone 8.0 and Windows Phone 8.1 is the back button management: as a consequence of the alignment with the Windows 8 platform (which doesn’t offer a hardware back key button), the default behavior when the Back button is pressed is to redirect the user to the previous application and not to the previous page. This doesn’t mean that it’s correct, from a user experience point of view, to keep this behavior: the user expects to go back to the previous page of your application when the Back button is pressed. To support the developer to correctly manage this scenario, all the Visual Studio templates for the Universal Windows apps (except the Blank App one) include a class called NavigationHelper, which, among other things, automatically intercepts the Back button pressed event and redirects the user to the previous page of the app.

However, if you’re using Caliburn Micro, you won’t need it: the framework will take care, automatically, of managing the back button for you. In the previous sample, you’ll notice the by pressing the Back button in the detail page, you’ll be correctly redirected to the main page of the app and not the previous application in the OS stack.

Wrapping up

In this post we’ve learned how to properly manage navigation in a Universal Windows app using Caliburn Micro. As usual, you can download a sample project to play with from the following link.

Caliburn Micro 2.0 in Universal Windows apps – The complete series

  1. The project setup
  2. Binding and actions
  3. Navigation

Samples available on GitHub

Posted in Windows 8, Windows Phone | Tagged , , | 7 Comments