Monday, 1 July 2013

Creating a Flyout using Prism for the Windows Runtime

Previously I extended the sample photo viewing app so that along with frame state, page state is serialized during suspension and de-serialized when the app reactivates following termination. This was achieved by marking properties whose values should survive termination with the custom [RestorableState] attribute.

In this blog post I’ll further extend the app so that a Flyout can be displayed by tapping on the photo on the PhotoPage. The Flyout will display basic photo information including filename, file type, resolution, and path. A series of value converters will be used to convert the photo information into a user friendly format for display.

Please note that this blog post and sample app uses the Flyout defined by Prism for the Windows Runtime, not the new Flyout control which is available in Windows 8.1.

Implementation

Creating the Flyout view

Prism expects to find any Flyouts in a folder named Views in the root folder of your project, with the Flyout names ending with “Flyout”. This allows you to use the FlyoutService’s default convention to display the view as a Flyout. The Flyout view should derive from the FlyoutView class, which is contained in the Microsoft.Practices.Prism.StoreApps project.

<prism:FlyoutView x:Class="PhotoViewer.Views.PhotoInformationFlyout"
                  ...
                  prism:ViewModelLocator.AutoWireViewModel="True">

The PhotoInformationFlyout simply binds to the sub-properties of the File property in the PhotoInformationFlyoutViewModel class. The PhotoInformationFlyout view is associated with the PhotoInformationFlyoutViewModel class by setting the AutoWireViewModel attached property of the ViewModelLocator object to true. If you want to override Prism’s default convention for locating, instantiating, and displaying Flyouts, you should override the CreateFlyoutView method from the MvvmAppBase class in your App class.

The PhotoInformationFlyout constructor must specify the width of the Flyout. The StandardFlyoutSize class provides two standard sizes for Flyouts – Narrow and Wide.

public PhotoInformationFlyout()
    : base(StandardFlyoutSize.Narrow)
{
    this.InitializeComponent();
}
Creating the Flyout view model

Flyout view models must derive from the IFlyoutViewModel interface. This interface specifies that implementing view models must implement CloseFlyout and GoBack properties, and an Open method. In implementing these properties your Flyout view model class should inherit from Prism’s BindableBase class, in order to provide property change notification.

public class PhotoInformationFlyoutViewModel : BindableBase, IFlyoutViewModel
{
    private FileInformation _file;
    private Action _closeFlyout;
    private Action _goBack;
 
    public FileInformation File 
    {
        get { return _file; }
        private set { SetProperty(ref _file, value); }
    }
 
    public Action CloseFlyout
    {
        get { return _closeFlyout; }
        set { SetProperty(ref _closeFlyout, value); }
    }
 
    public Action GoBack
    {
        get { return _goBack; }
        set { SetProperty(ref _goBack, value); }
    }
 
    public void Open(object parameter, Action successAction)
    {
        File = parameter as FileInformation;
    }
}

The PhotoInformationFlyoutViewModel class inherits from the BindableBase class and implements the IFlyoutViewModel interface. In addition, it provides a File property of type FileInformation. When the Open method is executed, by Prism’s FlyoutService class, the File property is set to the received FileInformation parameter. This ensures that the PhotoInformationFlyout, which binds to the File property of the PhotoInformationFlyoutViewModel, has data to display.

Registering the FlyoutService with Unity

In order to use the FlyoutService to display a Flyout you must first register it with the Unity dependency injection container (assuming you are using a DI container) in the OnInitialize method in your App class.

_container.RegisterInstance<IFlyoutService>(FlyoutService);

This code registers the FlyoutService instance created by the MvvmAppBase class with the container, as a singleton, based on it’s interface. This allows the PhotoPageViewModel class to take a dependency on the FlyoutService instance, in order to display the PhotoInformationFlyout.

Displaying the Flyout

The PhotoInformationFlyout is displayed by tapping on a photo on the PhotoPage. The Image control in the PhotoPage uses the ImageTappedToAction attached behaviour to handle the Tapped event in the PhotoPageViewModel class.

<Image behaviours:ImageTappedToAction.Action="{Binding DisplayPhotoInformationFlyoutAction}"
       HorizontalAlignment="Center"
       Source="{Binding Photo}"
       VerticalAlignment="Center" />

The DisplayPhotoInformationFlyoutAction property is initialized in the PhotoPageViewModel constructor to execute the DisplayPhotoInformationFlyout method.

private void DisplayPhotoInformationFlyout(object parameter)
{
    _flyoutService.ShowFlyout("PhotoInformation", _file, null);
}

The DisplayPhotoInformationFlyout method uses the FlyoutService instance, which is injected as a constructor parameter, to call the ShowFlyout method to display the PhotoInformationFlyout. The _file field specifies the FileInformation object that is passed into the PhotoInformationFlyoutViewModel class. As I’ve previously stated, if you want to override Prism’s default convention for locating, instantiating, and displaying Flyouts, you should override the CreateFlyoutView method from the MvvmAppBase class in your App class.

Summary

In this blog post I’ve extended the app so that a Flyout can be displayed by tapping on the photo on the PhotoPage. The PhotoInformationFlyout displays basic photo information including filename, file type, resolution, and path. A series of value converters are used to convert the photo information into a user friendly format for display.

The PhotoInformationFlyout derives from Prism’s FlyoutView class, with the PhotoInformationFlyoutViewModel class implementing the IFlyoutViewModel interface. The ShowFlyout method of Prism’s FlyoutService class is used to programmatically display the PhotoInformationFlyout.

The sample app can be downloaded here.

No comments:

Post a comment