Mobile Zone is brought to you in partnership with:

Developer enthusiast since the young age, my passion is mobile development and, in the last years, I focused on the Windows Phone platform. I'm engaged in many activities for Italian communities by blogging, writing articles and speaking about Windows Phone development. I'm member of the Italian community DotNetLombardia. Since 2012 I'm Microsoft MVP in the Windows Phone Development category and, actually, I work in Funambol as a Software Engineer for the Windows Phone and Windows 8 platforms. Matteo is a DZone MVB and is not an employee of DZone and has posted 36 posts at DZone. You can read more from them at their website. View Full User Profile

Using Caliburn Micro with Universal Windows App: Design Time Data

08.13.2014
| 3319 views |
  • submit to reddit

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 it 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, which 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 keepingthe 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.

Published at DZone with permission of Matteo Pagani, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)