Let’s continue our journey about using Prism in Universal Windows app development, by understanding how to manage a very important feature: navigation. Unless we’re talking about a really basic application, your project will likely contain more than one page. Consequently, we need to be able to navigate from one page to another. The problem is that, typically, the operation is performed using the Frame class, which can be accessed only in code behind, since the pages inherits from base Page class. To achieve the same result in a MVVM application, we need to use a special service that act as a wrapper of the Frame class and that can be accessed also from a ViewModel. Prism already offers this class: it’s called NavigationService and we’ve already seen it in the first post, when we’ve setup the infrastructure required by Prism to properly work. If you remember, the App.xaml.cs file contains the following method:

protected override Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
{
    NavigationService.Navigate("Main", null);
    return Task.FromResult<object>(null);
}

This method is invoked when the application is started and it’s used to redirect the user the user to the main page of the application. We’ve already described how to perform a basic navigation using the NavigationService: we call the Navigate() method, passing as parameter a string with the name of the View, without the Page suffix. In the previous sample, passing Main as parameter of the Navigate() method means that we want to redirect the user to a View in our project that is called MainPage.xaml.

Using the NavigationService in a ViewModel

To use the NavigationService in a ViewModel we need to use the dependency injection approach we’ve already seen in the first post. The App.xaml.cs file, in fact, contains also the following method:

protected override Task OnInitializeAsync(IActivatedEventArgs args)
{
    // Register MvvmAppBase services with the container so that view models can take dependencies on them
    _container.RegisterInstance<ISessionStateService>(SessionStateService);
    _container.RegisterInstance<INavigationService>(NavigationService);
    // Register any app specific types with the container

    // Set a factory for the ViewModelLocator to use the container to construct view models so their 
    // dependencies get injected by the container
    ViewModelLocationProvider.SetDefaultViewModelFactory((viewModelType) => _container.Resolve(viewModelType));
    return Task.FromResult<object>(null);
}

As you can see, among other things, the method takes of registering, inside the UnityContainer object, the INavigationService interface, by connecting it to the NavigationService implementation offered by Prism. This way, we’ll be able to use the NavigationService in a ViewModel simply by adding an INavigationService parameter to the ViewModel’s constructor, like in the following sample:

public class MainPageViewModel : ViewModel
{
    private readonly INavigationService _navigationService;

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

Now we have a reference to the Prism’s NavigationService, that we can use to perform navigation inside a ViewModel.

Managing the navigation events in a ViewModel

Another common requirement when you develop an Universal Windows app using the MVVM pattern is to find a way to intercept when the user is navigating to or away from the current page. In code behind, it’s easy to do it because we have access to two methods called OnNavigatedTo() and OnNavigatedFrom(): unfortunately, they are available only in the code behind class, since they are inherited from the base Page class.

Prism offers a simple way to manage these two navigation events in a ViewModel: as we’ve already seen in the previous posts, the ViewModels inherits from a base class called ViewModel. Thanks to this class, we are able to subscribe to the OnNavigatedTo() and OnNavigatedFrom() methods inside a ViewModel, like in the following sample:

public class MainPageViewModel : ViewModel
{
    public override void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode, Dictionary<string, object> viewModelState)
    {
        base.OnNavigatedTo(navigationParameter, navigationMode, viewModelState);
    }

    public override void OnNavigatedFrom(Dictionary<string, object> viewModelState, bool suspending)
    {
        base.OnNavigatedFrom(viewModelState, suspending);
 
    }
}

The OnNavigatedTo() method, especially, is very important, because it’s the best point where to load the data that will be displayed in the page. Some people, in fact, often use the ViewModel constructor to load the data: however, it’s not a good approach, especially in modern development. It often happens, in fact, that the data needs to be loaded using asynchronous methods, which are based on the async and await pattern. If you have some experience with this approach, you’ll know that a class constructor can’t be marked with the async keyword, so you won’t be able to call a method using the await prefix. This means that, for example, the following code won’t compile:

public class MainPageViewModel : ViewModel
{
    private readonly INavigationService _navigationService;
    private readonly IFeedService _feedService;
    private ObservableCollection<News> _news;

    public ObservableCollection<News> News
    {
        get { return _news; }
        set { SetProperty(ref _news, value); }
    }

    public MainPageViewModel(INavigationService navigationService, IFeedService feedService)
    {
        _navigationService = navigationService;
        _feedService = feedService;

        IEnumerable<News> news = await _feedService.GetNews();

        News = new ObservableCollection<News>();
        foreach (News item in news)
        {
            News.Add(item);
        }
    }        
}

I won’t describe in details how is defined the IFeedService class and how exactly works the GetNews() method: you can see all the details in the source code of the project that is published at https://github.com/qmatteoq/Prism-UniversalSample. For the moment, it’s important just to know that it’s an asynchronous method which, by using the SyndicationClient class provided by the Windows Runtime, downloads the RSS feed of this blog and parses it, to return the items as list of objects. Our goal is to display this list using a ListView control in the application: however, as I’ve previously mentioned, the previous code won’t compile, since I’m calling an asynchronous method (GetNews(), which is invoked with the await keyword) inside the ViewModel constructor, which can’t be marked with the async keyword.

The OnNavigatedTo(), instead, since it’s a sort of event handler (it manages the page navigation event), can be marked with the async keyword, so you can call asynchronous method in it without problems. Here is the correct approach to implement the previous sample:

public class MainPageViewModel : ViewModel
{
    private readonly INavigationService _navigationService;
    private readonly IFeedService _feedService;
    private ObservableCollection<News> _news;

    public ObservableCollection<News> News
    {
        get { return _news; }
        set { SetProperty(ref _news, value); }
    }

    public MainPageViewModel(INavigationService navigationService, IFeedService feedService)
    {
        _navigationService = navigationService;
        _feedService = feedService;
    }

    public override async void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode, Dictionary<string, object> viewModelState)
    {
        IEnumerable<News> news = await _feedService.GetNews();

        News = new ObservableCollection<News>();
        foreach (News item in news)
        {
            News.Add(item);
        }
    }
}

As you can see, the data loading operation is now performed in the OnNavigatedTo() method, which is marked with the async keyword and, consequently, we can call the GetNews() method using the await prefix without any issue. This code will compile and run just fine!

Passing parameters from one page to another

The OnNavigatedTo() can be useful also in another scenario: to pass parameters from one page to the another. Let’s use again the previous sample and let’s say that we have the following XAML page, which is the same we’ve seen in the previous post talking about commands with parameters:

<storeApps:VisualStateAwarePage
    x:Class="Prism_Navigation.Views.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Prism_Navigation"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:storeApps="using:Microsoft.Practices.Prism.StoreApps"
    xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm"
    xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
    xmlns:core="using:Microsoft.Xaml.Interactions.Core"
    mc:Ignorable="d"
    mvvm:ViewModelLocator.AutoWireViewModel="True"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <ListView ItemsSource="{Binding Path=News}" SelectionMode="Single" IsItemClickEnabled="True" Margin="12, 0, 12, 0">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Title}" Style="{StaticResource SubheaderTextBlockStyle}" 
                       TextWrapping="Wrap" />
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
            <interactivity:Interaction.Behaviors>
                <core:EventTriggerBehavior EventName="ItemClick">
                    <core:InvokeCommandAction Command="{Binding Path=ShowDetailCommand}" />
                </core:EventTriggerBehavior>
            </interactivity:Interaction.Behaviors>
        </ListView>
    </Grid>
</storeApps:VisualStateAwarePage>

We’re using a ListView control to display the list of news retrieved by the GetNews() method of the FeedService class. By using the behavior we’ve learned to use in the previous post, we’ve connected the ItemClick event to the ShowDetailCommand command in the ViewModel. Here is how the ShowDetailCommand’s definiton looks like:

public class MainPageViewModel : ViewModel
{
    public MainPageViewModel(INavigationService navigationService, IFeedService feedService)
    {
        _navigationService = navigationService;
        _feedService = feedService;

        ShowDetailCommand = new DelegateCommand<ItemClickEventArgs>((args) =>
        {
            News selectedNews = args.ClickedItem as News;
            _navigationService.Navigate("Detail", selectedNews);
        });
    }

    public DelegateCommand<ItemClickEventArgs> ShowDetailCommand { get; private set; }
}

The approach is the same we’ve seen in the previous post: we’ve defined a DelegateCommand<ItemClickEventArgs> and, consequently, we are able to retrieve, in the command definition, the item selected by the user. The difference is that, this time, after casting it as a News object, we pass it as second parameter of the Navigate() method of the NavigationService. This way, other than redirecting the user to a page called DetailPage.xaml (since we’re using the string Detail), we bring the information about the selected news, so that we can show the details.

The OnNavigatedTo() method can be used also to retrieve the parameter that we’ve passed from the NavigationService, thanks to one of the parameters called navigationParameter. The following sample shows the definition of the ViewModel of the detail page, which is the destination page of the navigation:

public class DetailPageViewModel : ViewModel
{
    private News _selectedNews;

    public News SelectedNews
    {
        get { return _selectedNews; }
        set { SetProperty(ref _selectedNews, value); }
    }

    public override void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode, Dictionary<string, object> viewModelState)
    {
        if (navigationParameter != null)
        {
            SelectedNews = navigationParameter as News;
        }
    }
}

As you can see, thanks to the navigationParameter, we are able to retrieve the selected item that has been passed by the previous page. In the sample, we simply cast it back to the News type (since it’s a generic object) and we display it to the user with the following XAML:

<Grid>
    <StackPanel>
        <TextBlock Text="{Binding Path=SelectedNews.Title}" />
        <TextBlock Text="{Binding Path=SelectedNews.Summary}" />
    </StackPanel>
</Grid>

Managing the back button in Windows Phone 8.1

One of the most important differences in the navigation system between Windows Phone 8.0 and Windows Phone 8.1 is the back button management: by default, in Windows Phone 8.0, the Back button always redirects the user to the previous page of the application. In Windows Phone 8.1, instead, to keep the behavior consistent with Windows 8.1 (which doesn’t offer a hardware button), the Back button redirect the user to the previous application. However, Microsoft don’t suggest to developers to use this approach: users, by pressing the back button, expect to go back to the previous page of the application since Windows Phone 7.0. Consequently, you need to override, in every page or in the App.xaml.cs, the HardwareButtons.BackPressed event and to perform a similar code:

private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
    Frame frame = Window.Current.Content as Frame;
    if (frame == null)
    {
        return;
    }

    if (frame.CanGoBack)
    {
        frame.GoBack();
        e.Handled = true;
    }
}

The code takes care of checking if there are pages in the backstack of the application (by checking the value of the CanGoBack property): if this is the case, we call the GoBack() method to perform a navigation to the previous page and we set the Handled property of the event handler as true, so that we prevent the operating system to manage it.

Well, the good news is that the MvvmAppBase class, which is the one that replaces the App one in a Prism application, already takes care of this for us: we won’t have to do nothing or to write additional code to support a proper Back key management in a Windows Phone 8.1 application.

Wrapping up

As usual, you can download the sample code related to this post from GitHub at the following URL: https://github.com/qmatteoq/Prism-UniversalSample

Index of the posts about Prism and Universal Windows app

  1. The basic concepts
  2. Binding and commands
  3. Advanced commands
  4. Navigation

Sample project: https://github.com/qmatteoq/Prism-UniversalSample

Tagged with:  

In the previous post we’ve learned the basic concepts that are required to implement the MVVM pattern using Prism in a Universal Windows app. In this post, we’ll continue our journey by exploring more details about using commands.

Managing secondary events with commands

When we use the Command property provided by the XAML control, we define the operation that should be executed when the user interacts with the primary event exposed by the control. For example, if it’s a Button, the Command property is connected to the Click event, so the operation is performed when the user taps on the button. However, in some situation we may have the requirement to subscribe to additional events that are exposed by the control. Let’s say, for example, that we want to manage the DoubleTapped event exposed by the Button control, which is triggered when you perform a double tap (instead of a single tap) on the button.

The goal can be achieved thanks to the behaviors provided by the Microsoft.Xaml.Interactivity library, which can be added to your project by right clicking on it, choosing Add reference and, in the Extensions section, enabling the Behaviors SDK (XAML) option. Now you’ll be able to use some behaviors that can be used to connect a secondary event to a command in the ViewModel. Here is a sample in the XAML page:

<storeApps:VisualStateAwarePage
    x:Class="Prism_AdvancedDemo.Views.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Prism_AdvancedDemo"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:storeApps="using:Microsoft.Practices.Prism.StoreApps"
    xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm"
    xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
    xmlns:core="using:Microsoft.Xaml.Interactions.Core"
    mc:Ignorable="d"
    mvvm:ViewModelLocator.AutoWireViewModel="True"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <Button Content="Double tap me">
            <interactivity:Interaction.Behaviors>
                <core:EventTriggerBehavior EventName="DoubleTapped">
                    <core:InvokeCommandAction Command="{Binding Path=DoubleTapCommand}" />
                </core:EventTriggerBehavior>
            </interactivity:Interaction.Behaviors>
        </Button>
    </Grid>
</storeApps:VisualStateAwarePage>

As you can, we’ve added two new namespaces to the XAML page definition: one is Microsoft.Xaml.Interactivity, the other one is Microsoft.Xaml.Interactions.Core. Thanks to these namespaces we are able to define, by using the attached property Interaction.Behaviors, the list of behaviors that we want to apply to the control (in our case, it’s the Button one). The behavior we’re going to use is called EventTriggerBehavior, which requires, by using the EventName property, the name of the event exposed by the control that we want to connect to it: in this case, it’s the DoubleTapped one. Inside the behavior we need to specify which action we want to perform: in this case, we need to use the InvokeCommandAction trigger, which is used to invoke an ICommand object defined in the ViewModel.

From the ViewModel point of view, nothing changes when it comes to define the DoubleTapCommand: it’s a standard implementation of the DelegateCommand class, as we’ve seen in the previous post.

public class MainPageViewModel : ViewModel
{
    public MainPageViewModel()
    {
        DoubleTapCommand = new DelegateCommand(async () =>
        {
            MessageDialog dialog = new MessageDialog("Double tap performed");
            await dialog.ShowAsync();
        });
    }


    public DelegateCommand DoubleTapCommand { get; private set; }
}

The command simply displays a message to the user, using a MessageDialog popup, every time it’s invoked.

Commands with parameters

Commands also support a way to pass parameters to the method that is invoked when the command is invoked. From the XAML point of view, it’s enough to set the parameter using the CommandParameter property offered by every control that support the Command property. The following sample shows how to set a parameter with a Button control:

<Button Content="Click me" Command="{Binding Path=DisplayMessageCommand}" CommandParameter="Text of the message" />

This approach is not a specific Prism feature, but it’s built-in in the XAML frameworks. What Prism offers is a a different implementation of the DelegateCommand class, which supports a parameter using generics. The following sample shows how to declare the DisplayMessageCommand so that it can receive a string parameter (since the value passed to the CommandParameter property is a text):

public class MainPageViewModel : ViewModel
{
    public MainPageViewModel()
    {         
        DisplayMessageCommand = new DelegateCommand<string>(async (args) =>
        {
            MessageDialog dialog = new MessageDialog(args);
            await dialog.ShowAsync();
        });
    }

   
    public DelegateCommand<string> DisplayMessageCommand { get; private set; }

}

There are two differences compared to a standard DelegateCommand implementation:

  • We’re using the DelegateCommand<T> type, where T is the parameter’s type (in our sample, it’s string).
  • The anonymous method that contains the code that is executed when the command is invoked contains a parameter, which is the value received by the CommandParameter property. In the sample, it’s called args and we use it to display to the user, using a MessageDialog, the parameter’s value.

Passing as parameter the event handler’s argument

When you work in code behind and you subscribe to an event handler, typically you get a parameter that contains some important information about the event. Let’s use, as sample, a ListView control, which is used to display a collection of items. One way to interact with the list (that is often used when you just need to know which item has been chosen, for example in a master – detail scenario) is to set the IsItemClickEnabled property to True: this way you can simply subscribe to the ItemClick event to get which item has been selected. Here is a sample usage of this event in the code behind:

private void NewsList_OnItemClick(object sender, ItemClickEventArgs e)
{
    News news = e.ClickedItem as News;
}

As you can see, the event handler contains a parameter (which type is ItemClickEventArgs) which stores, inside the ClickedItem property, the item that the user has selected in the ListView. In the previous sample, we’re displaying a collection of News objects so, thanks to a cast, we’re converting the selected item (which is a generic object) into the proper type.

This approach works fine in code behind, but what about MVVM? Since we have a command and not an event handler, how we can get, in the ViewModel, the event arguments received by the method (in this case, the ItemClickEventArgs object)? Prism makes things simple: it’s enough to create a DelegateCommand<T> property in the ViewModel, where T is the event argument’s type. Prism will automatically take care of passing, to the command, the event arguments of the event we’ve subscribed. Let’s consider the following sample:

<ListView ItemsSource="{Binding Path=News}" SelectionMode="Single" IsItemClickEnabled="True">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Title}" Style="{StaticResource SubheaderTextBlockStyle}" 
           TextWrapping="Wrap" />
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
    <interactivity:Interaction.Behaviors>
        <core:EventTriggerBehavior EventName="ItemClick">
            <core:InvokeCommandAction Command="{Binding Path=ShowDetailCommand}"
                      />
        </core:EventTriggerBehavior>
    </interactivity:Interaction.Behaviors>
</ListView>

We’re using the same approach we’ve seen before with the Button control: we’ve added an EventTriggerBehavior to the ListView control, which is connected to the ItemClick event. Then we applied an InvokeCommandAction, which invokes a command called ShowDetailCommand. As you can see, we’re not specyfing any command parameter. However, we are able to create a DelegateCommand object in the ViewModel that looks like this:

public class MainPageViewModel : ViewModel
{
    public MainPageViewModel()
    {
        ShowDetailCommand = new DelegateCommand<ItemClickEventArgs>((args) =>
        {
            News news = args.ClickedItem as News;
        });
    }

    public DelegateCommand<ItemClickEventArgs> ShowDetailCommand { get; private set; }
}

As you can see, we’ve not created a plain DelegateCommand object, but a DelegateCommand<T> one, where T is the event argument’s type we receive in the event handler (in our case, it’s ItemClickEventArgs). Prism will automatically inject, into the method, the event handler’s parameter: when we create the DelegateCommand<ItemClickEventArgs> object, we are able to access to this parameter and to perform the same operation we did in the code behind (which is accessing to the ClickedItem property and casting it to a News object). This way we would be able, for example, to use the Prism’s navigation service (which we’ll cover in the next post) to redirect the user to detail page, passing as parameter the selected item.

Wrapping up

As usual, you can find the sample code used for this post in the GitHub’s project available at the URL https://github.com/qmatteoq/Prism-UniversalSample

Index of the posts about Prism and Universal Windows app

  1. The basic concepts
  2. Binding and commands
  3. Advanced commands

Sample project: https://github.com/qmatteoq/Prism-UniversalSample

Tagged with:  

In the previous post we’ve seen the basic concepts about using Prism in a Universal Windows app: we’ve seen how to create our first project and how to setup the Prism infrastructure, so that we are able to use all the helpers and facilities offered by the framework. In this post we’ll see how to support the two most important MVVM concepts: binding and commands.

Binding

Binding is the way that, in MVVM, you use to connect properties that are declared in the ViewModel to controls that are placed in the View. This way, you’ll be able to perform two basic but important operations:

  • Display data in the page: every time you change a property in the ViewModel, the control that is connected to the property will automatically update itself to display the new value.
  • Receive input from the user: thanks to the two way binding, the communication channel between a property and a control can be bidirectional. This way, if the user interacts with a control in the page (for example, he writes something in a TextBox), the value will be stored in the property in the ViewModel.

The binding is based on the INotifyPropertyChanged interface, which should be implemented by ViewModels: this way, all the properties can notify to the controls in the View when its value is changed. Prism offers a base class that every ViewModel should implement which, among other things, gives us a quick way to implement this interface. The name of the class is VisualStateAwarePage: the name should help you to understand one of the other features of this class, which is a way to support, with visual states, the different layouts that a View can assume (portrait, landscape, snapped in case of a Windows Store app for Windows 8).

To support this class in our ViewModel we need to perform two operations: the first one is to replace the Page class from which every page inherits from with the VisualStateAwarePage one, which is included in the Microsoft.Practices.Prism.StoreApps namespace. Here is how a page of a Universal Windows app developed with Prism looks like:

<storeApps:VisualStateAwarePage
    x:Class="PrismDemo.Views.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PrismDemo.Views"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:storeApps="using:Microsoft.Practices.Prism.StoreApps"
    xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm"
    mc:Ignorable="d"
    mvvm:ViewModelLocator.AutoWireViewModel="True"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <!-- content of the page -->

</storeApps:VisualStateAwarePage>

As you can see, the base node it’s not called Page anymore, but it’s been replaced by the VisualStateAwarePage one.

The second step is to change also the code behind class of the page (the .xaml.cs file), so that it doesn’t inherit anymore from the Page class, but from the VisualStateAwarePage one. The following code shows a sample code behind definition:

using Microsoft.Practices.Prism.StoreApps;

namespace PrismDemo.Views
{
    public sealed partial class MainPage : VisualStateAwarePage
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
    }
}

Now that you’re properly set up the page, you’re ready to start using binding. The main concept behind binding is that, instead of using plain simple properties (with a standard getter and setter), you’re going to define properties that are able to propagate the changes to the user interface when its value changes. To make use of the mechanism offered by Prism to manage the notification propagation, you’ll need to inherit your ViewModels from the ViewModel class. The following sample shows a ViewModel with a simple property, which is defined using the Prism approach:

public class MainPageViewModel : ViewModel
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set { SetProperty(ref _name, value); }
    }

}

To assign a value to the property we use the SetProperty() method offered by Prism, which requires a reference to the private variable that holds its value (in this sample, it’s _name) and the value to assign (which is defined by the value keyword). Under the hood, the SetProperty() method, other than just assigning a value to the property, will take care of notifying the control that is in binding with it that the value is changed, by implementing, under the hood, the INotifyPropertyChanged interface. This way, the control in the XAML will update itself to reflect the change. Connecting this property in the ViewModel with a control in the XAML, now, doesn’t require any special knowledge, rather than standard binding. For example, here is how we can display the value of the Name property using a TextBlock control, by assigning it to the Text property using binding:

<TextBlock Text="{Binding Path=Name}" />

Otherwise, if other than just displaying the value we also need to retrieve the input from the user, we can simply apply the Mode attribute to the binding and set it to TwoWay, like in the following sample:

<TextBox Text="{Binding Path=Name, Mode=TwoWay" />

This way, when the user will write something in the box, we’ll be able to get the inserted text in the Name property of the ViewModel.

Commands

Commands are the mechanism offered by the XAML to support the user interaction without being forced to use event handlers. Typically, when you write an application without using the MVVM pattern, to manage the user’s interaction with the user interface (for example, he clicks on a button) you subscribe to a event handler: this way, a new method will be generated in code behind, which will contain the code that will be execute when the event is raised.

The downside of this approach is that it creates a strong connection between the View and the code: event handlers can be managed only in code behind, you can’t simply move it to a ViewModel. The solution is to use commands, which are special objects (that implement the ICommand interface) that define the operation to perform when the command is executed. The Windows Runtime offers only the basic interface to support commands, which is ICommand: a developer, typically, would have to create its own class to implement this interface. However, al the MVVM frameworks usually offer it and Prism makes no exception: in this case, the class is called DelegateCommand. Let’s see a sample about how to define a command in a ViewModel:

public class MainPageViewModel : ViewModel
{

    public MainPageViewModel()
    {
        SayHelloCommand = new DelegateCommand(() =>
        {
            Message = string.Format("Hello {0}", Name);
        });
    }

    public DelegateCommand SayHelloCommand { get; private set; }


    private string _name;

    public string Name
    {
        get { return _name; }
        set
        { SetProperty(ref _name, value); }
    }

    private string _message;

    public string Message
    {
        get { return _message; }
        set { SetProperty(ref _message, value); }
    }
}

As you can see, we’ve defined a new property, which type is DelegateCommand: in this case, we don’t need to use the SetProperty() method to define it, since a command won’t change implementation at runtime, so it will be set only by the ViewModel when it’s instantiated. It’s what we do in the ViewModel constructor (the method called MainPageViewModel()): we create a new DelegateCommand and we pass, as parameter,  an anonymous method that defines the operation to execute when the command is invoked. In this sample, we display to the user the message “Hello” followed by his name, that we have received in the property called Name.

Here is how the View connected to this ViewModel looks like:

<storeApps:VisualStateAwarePage
    x:Class="PrismDemo.Views.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PrismDemo.Views"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:storeApps="using:Microsoft.Practices.Prism.StoreApps"
    xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm"
    mc:Ignorable="d"
    mvvm:ViewModelLocator.AutoWireViewModel="True"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <StackPanel Margin="12, 0, 12, 0">
            <TextBox Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
            <TextBlock Text="{Binding Path=Message}" Style="{StaticResource HeaderTextBlockStyle}" />
        </StackPanel>
    </Grid>
    
    <storeApps:VisualStateAwarePage.BottomAppBar>
        <CommandBar>
            <CommandBar.PrimaryCommands>
                <AppBarButton Label="confirm" Icon="Accept" Command="{Binding Path=SayHelloCommand}" />
            </CommandBar.PrimaryCommands>
        </CommandBar>
    </storeApps:VisualStateAwarePage.BottomAppBar>
</storeApps:VisualStateAwarePage>

As you can see, we’ve added a TextBox control (which we’re going to use to collect the user’s name), a TextBlock control (which will display the hello message) and a CommandBar, which contains the button that the user will have to click to see the message. The button, which is an AppBarButton control, shows how to use commands: we simply put in binding the Command property of the control with the DelegateCommand’s object we’ve defined in the ViewModel. Now, every time the user will press the button, the operation we’ve defined in the command will be executed. 

Enabling and disabling commands

One of the most powerful features provided by commands is the automatic support to the state management. With a simple boolean condition, we can control if the command should be enabled or not: the control that is connected to the command will automatically change his appearance to reflect this status. This means that if, in the previous sample, the SayHelloCommand is marked as disabled, the AppBarButton control will be grayed and the user won’t be able to click on it.

To support this feature, you just need to pass a boolean condition as second parameter when you define the DelegateCommand object, like in the following sample:

public MainPageViewModel()
{
    SayHelloCommand = new DelegateCommand(() =>
    {
        Message = string.Format("Hello {0}", Name);
    }, () => !string.IsNullOrEmpty(Name));
}

As you can see, the second parameter is a boolean condition that checks if the Name property contains an empty value or not: this way, in case the user doesn’t type anything in the TextBox control, we disable the button, since we are not able to display the hello message.

There’s one last step to do to properly support this feature: the application is not able, automatically, to know when the boolean condition that we’ve specified could have changed, so we need to explicitly tell it. We do this by calling the RaiseCanExecuteChanged() method offered by the DelegateCommand class, which tells to the command to evaluate again his status. It’s up to us to decide when it’s the best moment to call it, according to the purpose of the command: in our sample, since we want to avoid that the user can press the button if he hasn’t written anything in the box, we’re going to evaluate the status of the command every time the value of the Name property changes. Here is how the definition of the Name property changes to support our scenario:

private string _name;

public string Name
{
    get { return _name; }
    set
    {
        SayHelloCommand.RaiseCanExecuteChanged();
        SetProperty(ref _name, value);
    }
}

Simply, before calling the SetProperty() method to save the value and update the control, we call the RaiseCanExecuteChanged() method of the SayHelloCommand object.

Wrapping up

In this post we’ve seen the basic concepts which are important to start writing a Universal Windows app using prism: binding and commands. In the next posts we’ll cover more advanced scenarios, like navigation, state management, advanced commands features, etc. You find this post’s sample on GitHub: https://github.com/qmatteoq/Prism-UniversalSample

Index of the posts about Prism and Universal Windows app

  1. The basic concepts
  2. Binding and commands
  3. Advanced commands

Sample project: https://github.com/qmatteoq/Prism-UniversalSample

Tagged with:  

In the latest days I’ve started to work with Prism for Universal Windows apps and I’ve decided to share my experience with you. What is Prism? If you’re a long time Microsoft developer, you’ll probably already know it: it’s a very popular MVVM (Model-View-ViewModel) framework created by the Patterns & Practices division in Microsoft, with the goal to help developers to implement the MVVM pattern in their application and to support the most common scenarios.

Recently, the division has released a Prism version which is completely compatible with the Windows Runtime and, consequently, with Universal Windows apps development: the purpose of this series of blog posts is to see how to use it for this scenario and how it can help you developing a MVVM application.

I won’t discuss in details the advantages of using the MVVM pattern: I’ve already talked about this topic in the posts series about Caliburn Micro.

Prism vs the other toolkits and frameworks

How does Prism compare to the other popular MVVM toolkits and frameworks, like MVVM Light and Caliburn Micro? After playing a bit with it, I’ve reached the conclusion that it tries to take the best of the both worlds. Definitely, it’s much more similar to Caliburn Micro than MVVM Light: in fact, we’re talking about a framework, which offers many built-in classes and helpers that are useful to manage specific scenarios of the platform (like navigation, state management, etc.). Moreover, like Caliburn Micro, it uses some special classes that replace the native ones (like the App class or the Page class), which acts as a bootstrapper to properly setup all the infrastructure required by Prism to properly work.

However, one of the cons of Caliburn Micro is that it’s not ideal to developers that are working with MVVM for the first time: despite being very powerful, all the naming conventions tend to hide all the basic concepts behind the pattern, like the binding, the DataContext or the usage of the INotifyPropertyChanged interface. Prism, instead, except for some minor scenarios (we’ll see the details later) is still based on the standard MVVM fundamentals, so it uses concepts that should be familiar to every XAML developer like binding or commands.

The project setup

Let’s see how to create our first Universal Windows app using Prism: the first step is to create a new Universal Windows app project in Visual Studio, which will create the usual solution with a shared project, a Windows 8.1 one and a Windows Phone 8.1 one. If you’re familiar with Universal Windows app development, you’ll know that the shared project isn’t a real library, but it’s just a collection of shared resources (like classes, assets and XAML controls) which are linked to the two other projects. Consequently, you can’t add a reference to a third party library to the shared project: references are taken directly by the main platforms specific projects. The first step is, by using NuGet, to install both in the Windows and in the Windows Phone project the Prism.StoreApp library, which is the Prism version specific for Windows Store Apps.

The second step is optional, but highly recommended, since we’re going to use this approach in the next samples: when we talked about Caliburn Micro we’ve learned a bit more about dependency injection, which is a way to create objects at runtime instead of compile time. The pros of this approach is that we are able to easily change the implementation of a class (for example, because we want to swap a real class with a fake one that provides fake data at design time) without having to modify all the ViewModels that use it.

Also Prism supports dependency injection and it’s the best way to manage the dependencies of the ViewModels from other services of our application (like a navigation service, or a data service that retrieves our application’s data, etc.). The most widely used dependency injection’s container for Prism is Unity, which is also provided by the Pattern & Practices division by Microsoft: the next step, consequently, is to use again NuGet to install Unity in both project. It’s important to highlight that you’ll need to enable the option to extend the search also in pre-release packages: the latest stable version, in fact, doesn’t support yet Windows Phone 8.1, so you’ll get an installation error if you try to add it.

Convert the application into a Prism application

The first step to convert the Universal app into a Prism based app is to configure the bootstrapper: with this term, I mean the procedure that is required by the framework to properly initialize all the infrastructure required to work. In Universal Windows apps, the bootstrapper is the App class itself: we’re going to redefine the App class, so that it doesn’t inherit anymore from the native Application class, but from a Prism classed called MvvmAppBase.

To do this you need to follow two steps: the first one is to change the definition of the App class in the XAML, in the file App.xaml. You’ll need to add a new namespace, which is the one where the MvvmAppBase class is defined: the namespace is Microsoft.Practices.Prism.Mvvm. The second step is to replace the base Application tag with the MvvmAppBase one. Here is how the App.xaml file will look like at the end:

<mvvm:MvvmAppBase
    x:Class="PrismDemo.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PrismDemo"
    xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm">

</mvvm:MvvmAppBase>

The second step, instead, is to change the App class code, so you’ll need to edit the App.xaml.cs file: the first thing to do is to replace the class where the App object inherits from, which isn’t anymore Application but MvvmAppBase. Then, you’ll need to remove all the code and keep just the App constructor: Prism, in fact, offers its own way to manage the different application’s lifecycle events (like launched, activated, suspended, etc.).

Here is how a base App class for a Prism project looks like:

sealed partial class App : MvvmAppBase
{
    public App()
    {
        this.InitializeComponent();
    }

}

We’re not done yet in setting up the bootstrapper but, first, we need to create our first page, so that it will be easier to understand the next steps. As I’ve mentioned before, one of the advantages of Prism over Caliburn is that, despite being a powerful framework, it doesn’t hide all the basic MVVM infrastructure. However, there’s an exception: like in Caliburn, the connection between a View and a ViewModel is performed using a naming convention. You can use also another approach if you prefer (like using a ViewModelLocator or by directly binding the ViewModel as data context of the View), but the naming convention one is the easiest to use to take advantage of all the Prims features. The naming convention is very simple and it reminds the one used by Caliburn: you’ll have to place your ViewModels into a folder of your project called ViewModels, while the Views will be placed in a folder called Views. Since you’re working on a Universal Windows app, typically you’re going to create the ViewModels folder into the Shared project (since the ViewModels will be shared across the two platforms), while the Views folder will be created in the platform specific project, so that you can optimize the user interface for the two platforms.

There’s also another naming convention to follow, which is about the name of the files:

  • The View should end with the Page suffix (like MainPage).
  • The ViewModel should have the same name of the View, plus the ViewModel suffix (so, for example, the ViewModel connected to a page called MainPage will be named MainPageViewModel).

solution

Now that you have created your first page of the application, you’re going to need to tell to Prism that it’s the default one, that needs to be loaded when the application starts. You’re going to achieve this goal by overriding in the App class one of the methods offered by the MvvmAppBase class, which is OnLaunchApplicationAsync(). Here is how it looks like in a typical Universal Windows app:

protected override Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
{
    NavigationService.Navigate("Main", null);
    return Task.FromResult<object>(null);
}

The method uses one of the built in helpers offered by Prism, that we’ll cover in details in the next posts: it’s a class called NavigationService, which is used to perform navigation from one page to another. To navigate to another page you need to use the Navigate() method, which accepts as first parameter the name of the page, which is the name of the View without the Page suffix: in the previous sample, by passing as parameter the value Main we’re assuming that, in the Views folder of our project, we have a page called MainPage.xaml. For the moment, ignore the second parameter, which is simply set to null: it’s the optional parameter that we can pass to the destination page.

The last line of code executed by the operation is a “workaround”: as you can see, the OnLaunchApplicationAsync() method returns a Task, so that you can perform asynchronous operations inside it. Since, in this case, we’re not performing any of them, we’re returning a “fake” one by using the Task.FromResult() method and passing null as parameter.

Setting up the dependency injection

The last step before starting working for real on the application is to configure the dependency injection container: as already mentioned, we’re going to use Unity. The container initialization is made in a method offered by the MvvmAppBase called OnInitializeAsync(), which is executed when the application is initialized for the first time. The approach here is the same we’ve seen in Caliburn: we are able to register own services, so that they will be automatically injected in the ViewModels when we’re going to use them. However, we have also to register some of the built-in services, so that we can use them in the other ViewModels: they are the NavigationService (which we’ve already seen and it’s used to perform navigation from one page to the other) and the SessionStateService, which we’ll see in details in another post. For the moment, it’s important just to know that it’s a helper to make it easier for developer to manage the suspension and termination of the app.

If you have some experience with Caliburn or MVVM Light, you’ll know that one of the required step to properly set up the dependency injection is to register, inside the container (which is the class that takes care of dispatching the objects when required), all the ViewModels of the project. With Prism this is not required: thanks to the naming convention previously described, in fact, we are able to tell to Prism (using a class called ViewModelLocatorProvider) that we want to automatically register every available ViewModel.

Here is how the complete App.xaml.cs looks like:

sealed partial class App : MvvmAppBase
{
    IUnityContainer _container = new UnityContainer();
    public App()
    {
        this.InitializeComponent();
    }

    protected override Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
    {
        NavigationService.Navigate("Main", null);
        return Task.FromResult<object>(null);
    }

    protected override Task OnInitializeAsync(IActivatedEventArgs args)
    {
        // Register MvvmAppBase services with the container so that view models can take dependencies on them
        _container.RegisterInstance<ISessionStateService>(SessionStateService);
        _container.RegisterInstance<INavigationService>(NavigationService);
        // Register any app specific types with the container

        // Set a factory for the ViewModelLocator to use the container to construct view models so their 
        // dependencies get injected by the container
        ViewModelLocationProvider.SetDefaultViewModelFactory((viewModelType) => _container.Resolve(viewModelType));
        return Task.FromResult<object>(null);
    }
}

In the previous code you can see the three required steps to setup the dependency injection:

  • We create a property which type is IUnityContainer and we create a new instance.
  • We register, by using the RegisterInstance<T>(), the previously described SessionStateService and NavigationService.
  • By using the SetDefaultViewModelFactory() method of the ViewModelLocationProvider class, we are able to automatically register every ViewModel we have in our project, so that it can be automatically connected to the View when required..

    Now we have defined the proper infrastructure required by Prism: there’s only one last step to, which is to tell to every View in our application which ViewModel to use. We achieve this by adding, in the Page class in the XAML, a property offered by Prism called AutoWireViewModel, which is offered by the ViewModelLocator class: by setting it to True, we enable the naming convention, so the View will automatically look for its own ViewModel and will assign it as DataContext. Here is how a page in a Prism application looks like:

    <Page
        x:Class="PrismDemo.Views.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:PrismDemo.Views"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:mvvm="using:Microsoft.Practices.Prism.Mvvm"
        mc:Ignorable="d"
        mvvm:ViewModelLocator.AutoWireViewModel="True"
    
    </Page>
    

    Wrapping up

    So far, we’ve just seen how Prism works and how to setup the project. In the next post, we’re going to start creating the application for real, by seeing how to use binding and how to define commands to manage the user interaction. If you want a sneak peak of a real project, you can find the sample we’re going to use in the next post on GitHub at the URL https://github.com/qmatteoq/Prism-UniversalSample

    Index of the posts about Prism and Universal Windows app

    1. The basic concepts
    2. Binding and commands
    3. Advanced commands

    Sample project: https://github.com/qmatteoq/Prism-UniversalSample

  • Tagged with:  

    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

    Tagged with:  

    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!

    Tagged with:  

    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.

    Tagged with:  

    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!

    Tagged with:  

    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

    Tagged with:  

    In the previous post we’ve learned how to properly set up Caliburn Micro in a Universal Windows app. In this post we’re going to recap all the most important naming conventions that can be used to connect our data to the user interface.

    Connecting a property in the ViewModel to a control in the View

    The simplest way to connect a property in the ViewModel to a control in the View is using binding. Let’s say you have a ViewModel defined in the following way:

    namespace CaliburnDemo.ViewModels
    {
        public class MainPageViewModel : PropertyChangedBase
        {
            private string name;
            public string Name
            {
                get { return name; }
                set
                {
                    name = value;
                    NotifyOfPropertyChange(() => Name);
                }
            }
        }
    }

    You can notice two things:

    • PropertyChangedBase is the simplest class offered by Caliburn Micro to support the propagation of properties: this way, every time we change the value of the property in the ViewModel, the control that is placed in binding with the property will update its visual layout to reflect the changes.
    • NotifyOfPropertyChange() is the method to call to propagate the change to the UI.

    You can connect the property Name to the View using the standard binding approach, like in the following sample:

    <TextBlock Text="{Binding Name}" />

    Otherwise, you can use the Caliburn Micro naming conventions, which requires to give to the control (using the x:Name property) the same name of the property in the ViewModel you want to connect. In the previous sample, you would have simply defined the TextBlock control in the following way:

    <TextBlock x:Name="Name" />

    When you use this naming convention, automatically the property called Name in the ViewModel will be bound to the Text property of the TextBlock control. In addition, it will be a two-way binding and every change of the source will be reflected to the target and vice versa immediately. This means that if you’re using a TextBox, for example, every time the user presses a key the updated string will be sent to the ViewModel.

    Performing an action

    Another common scenario while developing a Windows app is performing an action: for example, the user presses a button and you want to perform an operation. In MVVM, this is typically achieved using commands, which are a way to define an action without being constrained by using the events exposed by the control. Event handlers, in fact, can be managed only from in code behind: you can’t subscribe, for example, to the Click event exposed by a button in a class different than the code behind one (like a ViewModel).

    Caliburn Micro offers a simple naming convention to achieve this result: give to the control the same name of the method that is defined in the ViewModel.

    Let’s say that you have a Button control which is defined in the following way:

    <Button Content="Conferma" x:Name="Confirm" />

    Since the name of the control is Confirm, when it’s pressed it will trigger a method with the same name defined in the ViewModel, like in the following sample:

    public void Confirm()
    {
        Greetings = string.Format("Hello, {0}!", Name);
    }

    One of the features offered by the command approach is that you’re able to define if the action can be executed or not; the cool thing is that the control that is connected to the action will automatically change its visual status accordingly. The most common example is a page that acts as a form, that the user can fill: until all the fields are filled, the button to send the form should be disabled.

    This goal is achieved by creating a boolean property in the ViewModel, which name should be the same of the method plus the prefix Can. In the previous example, to control the method Confirm() we need to create a property called CanConfirm, which should return true or false, based on the condition we need to manage.

    For example, let’s say that if the Name property is empty, the action should be disabled. We can achieve this result by defining the CanConfirm property in the following way:

    public bool CanConfirm
    {
        get { return !string.IsNullOrWhiteSpace(Name); }
    }

    There’s just one thing missing: every time the Name property changes, we need to evaluate again the CanConfirm property. We can achieve this result simply by calling the NotifyOfPropertyChange()  also for the CanConfirm property every time the value of the Name property changes, like in the following sample:

    private string name;
    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            NotifyOfPropertyChange(() => Name);
            NotifyOfPropertyChange(() => CanConfirm);
        }
    }

    This way, as soon as the Name property is not empty, the Button control that is connected to the Confirm() method will be enabled; otherwise, it will stay in the disabled state.

    One of the best new features in Windows Phone Store apps is that now the Application Bar (managed using the CommandBar control) fully supports binding: this means that you can use the same exact naming convention also with the AppBarButton control, like in the following sample:

    <Page.BottomAppBar>
        <CommandBar>
            <CommandBar.PrimaryCommands>
                <AppBarButton Icon="Accept" Label="Confirm"
                             x:Name="Confirm" />
            </CommandBar.PrimaryCommands>
        </CommandBar>
    </Page.BottomAppBar>

     

    Since the name of this button is Confirm, the method with the same name defined in the ViewModel will be called when the user will tap it.

    Advanced actions management

    The previous naming convention works fine when it comes to manage the standard command connected to the control, like the Click event for a Button. But what if you need to manage some extra events? Let’s say, for example, that you want to manage the DoubleTapped event, which is triggered when the button is tapped twice. In this case, you can use a special Caliburn Micro class called Message, which allows to attach a method to any event exposed by the control.

    First, you need to add the Caliburn Micro namespace in the Page definition in the XAML:

    <Page
        x:Class="MoviesTracker.Views.MainPageView"
        xmlns:viewModels="using:MoviesTracker.ViewModels"
        xmlns:micro="using:Caliburn.Micro"
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    
    </Page>

    Then you can use the attached property Attach exposed by the Message class, like in the following sample:

    <Button Content="Conferma" x:Name="Confirm" micro:Message.Attach="[Event DoubleTapped] = [Action Confirm]" />

    The Attach property requires a value split in two parts, each of it defined inside square brackets. The first one is marked with the keyword Event and it requires the name of the event we want to manage (in our case, DoubleTapped). The second one, instead, is marked with the keyword Action and it’s the name of the method defined in the ViewModel that should be triggered when the event is raised.

    One cool thing is that you can pass some special values to name of the action, which can be used to pass a parameter to the method in the ViewModel. Let’s see a real example with the ListView control, which is one of the new and powerful Windows Runtime controls to display collection of items:

    <ListView ItemTemplate="{StaticResource OnlineMoviesTemplate}"
    ItemsSource="{Binding Movies}"
    IsItemClickEnabled="True"
    SelectionMode="None"
    micro:Message.Attach="[Event ItemClick] = [Action GoToDetail($eventArgs)]" />

    The ListView control offers a new way to manage the list that is useful when you don’t really want to provide a way to select items, but you just need to redirect the user to a detail page to see more information about the selected item. You can achieve this result by setting the SelectionMode property of the control to None and the IsItemClickEnabled one to True. This way, every time the user will select an item from the list, the selection won’t be triggered, but a specific event called ItemClick will be invoked: in the parameter of the event handler you’ll get the item that has been selected.

    The previous sample shows you a powerful special value that can be very useful in this scenario: the GoToDetail() action is invoked with the parameter $eventArgs. This way, the method in the ViewModel will receive the parameter of the event, exactly like if we are managing it in the code behind using an event handler. Here is how the GoToDetail() method in the ViewModel looks like:

    public void GoToDetail(ItemClickEventArgs args)
    {
        Movie selectedMovie = args.ClickedItem as Movie;
        _navigationService.NavigateToViewModel<DetailMovieViewModel>(selectedMovie.Id);
    }

     

    The parameter’s type we receive is exactly the same as we would have used the event handler in code behind: in this case, it’s ItemClickEventArgs. The sample shows you how it’s easy to use it to retrieve the needed information, in this case the selected item, which is stored inside the ClickedItem property. This sample is taken from my Movies Tracker application, so we’re dealing with a collection of movies: this method retrieves the selected movie and redirects the user to the detail page. For the moment, ignore the NavigationService usage: we’re going to talk about it in another post.

    Another cool thing in Caliburn is that, in the bootstrapper, you can create your own special parameters to use with the Attach property. For example, let’s try to add the following line of code in the Configure() method of the App.xaml.cs file:

    MessageBinder.SpecialValues.Add("$clickeditem", c => ((ItemClickEventArgs)c.EventArgs).ClickedItem);

    By using the MessageBinder class, we are telling to Callburn Micro that we want to create a new special parameter called $clickeditem, which will be connected to the ClickedItem property of the ItemClickEventArgs class. This way, we can change the ListView definition in XAML in the following way:

     

    <ListView ItemTemplate="{StaticResource OnlineMoviesTemplate}"
    ItemsSource="{Binding Movies}"
    IsItemClickEnabled="True"
    SelectionMode="None"
    micro:Message.Attach="[Event ItemClick] = [Action GoToDetail($clickeditem)]" />

    As you can see, we changed the name of the parameter we pass to the action: it’s now called $clickeditem, which is the same name we defined in the bootstrapper using the MessageBinder.

    By applying this change we can simplify the GoToDetail() method we’ve defined in the ViewModel:

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

    Thanks to the new parameter we’ve created, the method will directly receive the value of the ClickedItem property: Caliburn Micro is able to apply the cast for you, so we can simply define the parameter’s type as Movie and the framework will take care of converting the ClickedItem property in the expected value.

    There are also some other special parameters in Caliburn Micro, like $dataContext (to get access to the DataContext of the control that invoked the action) or $source (which is a reference to the control that invoked the action). You can find the list of all the available parameters in the official documentation.

    Wrapping up

    In this post we’ve learned the basic naming conventions and how to manage actions in a Universal Windows app with Caliburn Micro. In the next post we’ll see some advanced scenario which have changed in this new version of Caliburn Micro, like navigation.

    In the meanwhile, you can play with the sample project.

    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

    Tagged with:  
    Animated Social Media Icons Powered by Acurax Wordpress Development Company