How to Use Cimbalino Windows Phone Toolkit Media Library – MediaLibraryService

The purpose of this sample is to show how to use the Cimbalino Windows Phone Toolkit Media Library, MediaLibraryService.

Introduction

The Cimbalino Windows Phone Toolkit delivers a set of useful and powerful MVVM-compatible tools and services to help developers build Silverlight applications for Windows Phone. The Toolkit is divided in projects that deliver various features, ranging from base MVVM services and helpers, through to code for background agents and for accessing the media library, location services and so on. Cimbalino.Phone.Toolkit.MediaLibrary is a MVVM compatible services for media library access.

IMediaLibraryService represents an interface for a service capable of saving images to the media library. The implementation is MediaLibraryService.

Building the example code

The source code for the code example is available here: MediaLibraryService Sample (Github).

To build the source code you will also need the MVVM Light Toolkit and the Cimbalino Windows Phone Toolkit. Their packages are available in the Nuget Package Manager.

Note: You must specify the following capabilities in the app manifest: ID_CAP_MEDIALIB_PHOTO.

Registering the service

Register the service in the ViewModelLocator constructor as highlighted below:

  1. using Cimbalino.Phone.Toolkit.Services;  
  2. using GalaSoft.MvvmLight;  
  3. using GalaSoft.MvvmLight.Ioc;  
  4. using Microsoft.Practices.ServiceLocation;  
  5.   
  6. /// <summary>  
  7. /// This class contains static references to all the view models in the  
  8. /// application and provides an entry point for the bindings.  
  9. /// </summary>  
  10. public class ViewModelLocator  
  11. {  
  12.     /// <summary>  
  13.     /// Initializes a new instance of the ViewModelLocator class.  
  14.     /// </summary>  
  15.     public ViewModelLocator()  
  16.     {  
  17.         ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);  
  18.   
  19.         if (!SimpleIoc.Default.IsRegistered<INavigationService>())  
  20.         {  
  21.             SimpleIoc.Default.Register<INavigationService, NavigationService>();  
  22.         }  
  23.   
  24.         if (!SimpleIoc.Default.IsRegistered<IMediaLibraryService>())  
  25.         {  
  26.             SimpleIoc.Default.Register<IMediaLibraryService, MediaLibraryService>();  
  27.         }  
  28.         if (!SimpleIoc.Default.IsRegistered<ICameraCaptureService>())  
  29.         {  
  30.             SimpleIoc.Default.Register<ICameraCaptureService, CameraCaptureService>();  
  31.         }  
  32.         SimpleIoc.Default.Register<MainViewModel>();  
  33.         SimpleIoc.Default.Register<AlbunsViewModel>();  
  34.         SimpleIoc.Default.Register<PicturesViewModel>();  
  35.     }  
  36.   
  37.     /// <summary>  
  38.     /// Gets the main view model.  
  39.     /// </summary>  
  40.     /// <value>  
  41.     /// The main view model.  
  42.     /// </value>  
  43.     public MainViewModel MainViewModel  
  44.     {  
  45.         get  
  46.         {  
  47.             return ServiceLocator.Current.GetInstance<MainViewModel>();  
  48.         }  
  49.     }  
  50.   
  51.     /// <summary>  
  52.     /// Gets the albuns view model.  
  53.     /// </summary>  
  54.     /// <value>  
  55.     /// The albuns view model.  
  56.     /// </value>  
  57.     public AlbunsViewModel AlbunsViewModel  
  58.     {  
  59.         get  
  60.         {  
  61.             return ServiceLocator.Current.GetInstance<AlbunsViewModel>();  
  62.         }  
  63.     }  
  64.   
  65.     /// <summary>  
  66.     /// Gets the pictures view model.  
  67.     /// </summary>  
  68.     /// <value>  
  69.     /// The pictures view model.  
  70.     /// </value>  
  71.     public PicturesViewModel PicturesViewModel  
  72.     {  
  73.         get  
  74.         {  
  75.             return ServiceLocator.Current.GetInstance<PicturesViewModel>();  
  76.         }  
  77.     }  
  78.   
  79.     /// <summary>  
  80.     /// Cleanups.  
  81.     /// </summary>  
  82.     public static void Cleanup()  
  83.     {  
  84.         // TODO Clear the ViewModels  
  85.         var viewModelLocator = (ViewModelLocator)App.Current.Resources["Locator"];  
  86.         viewModelLocator.MainViewModel.Cleanup();  
  87.     }  
  88. }  
Implementing the ViewModel

Then we should implement the MainViewModel as in the following.
  1. using System;  
  2.     using System.Windows;  
  3.     using System.Windows.Input;  
  4.     using System.Windows.Threading;  
  5.    
  6.     using Cimbalino.Phone.Toolkit.Services;  
  7.    
  8.     using GalaSoft.MvvmLight.Command;  
  9.     using GalaSoft.MvvmLight;  
  10.    
  11.     /// <summary>  
  12.     /// This class contains properties that the main View can data bind to.  
  13.     /// </summary>  
  14.     public class MainViewModel : ViewModelBase  
  15.     {  
  16.         /// <summary>  
  17.         /// The navigation service  
  18.         /// </summary>  
  19.         private readonly INavigationService _navigationService;  
  20.    
  21.         /// <summary>  
  22.         /// The media library service  
  23.         /// </summary>  
  24.         private readonly IMediaLibraryService _mediaLibraryService;  
  25.    
  26.         /// <summary>  
  27.         /// The camera capture service  
  28.         /// </summary>  
  29.         private readonly ICameraCaptureService _cameraCaptureService;  
  30.    
  31.         /// <summary>  
  32.         /// Initializes a new instance of the MainViewModel class.  
  33.         /// </summary>  
  34.         /// <param name="navigationService">The navigation service.</param>  
  35.         /// <param name="mediaLibraryService">The media library service.</param>  
  36.         /// <param name="cameraCaptureService">The camera capture service.</param>  
  37.         public MainViewModel(INavigationService navigationService, IMediaLibraryService mediaLibraryService, ICameraCaptureService cameraCaptureService)  
  38.         {  
  39.             _navigationService = navigationService;  
  40.             _mediaLibraryService = mediaLibraryService;  
  41.             _cameraCaptureService = cameraCaptureService;  
  42.             ShowAlbunsCommand =new RelayCommand(ShowAlbuns);  
  43.             ShowPicturesCommand = new RelayCommand(ShowPictures);  
  44.             SavePictureCommand = new RelayCommand(SavePicture);  
  45.         }  
  46.    
  47.         /// <summary>  
  48.         /// Saves the picture.  
  49.         /// </summary>  
  50.         private void SavePicture()  
  51.         {  
  52.             _cameraCaptureService.Show(CameraCapetureResult);  
  53.         }  
  54.    
  55.         /// <summary>  
  56.         /// Shows the pictures.  
  57.         /// </summary>  
  58.         private void ShowPictures()  
  59.         {  
  60.             _navigationService.NavigateTo(new Uri("/PicturesPage.xaml", UriKind.Relative));  
  61.         }  
  62.    
  63.         /// <summary>  
  64.         /// Shows the albuns.  
  65.         /// </summary>  
  66.         private void ShowAlbuns()  
  67.         {  
  68.             _navigationService.NavigateTo(new Uri("/AlbunsPage.xaml", UriKind.Relative));  
  69.         }  
  70.    
  71.         /// <summary>  
  72.         /// Gets the show albuns command.  
  73.         /// </summary>  
  74.         /// <value>  
  75.         /// The show albuns.  
  76.         /// </value>  
  77.         public ICommand ShowAlbunsCommand { getprivate set; }  
  78.         /// <summary>  
  79.         /// Gets the show pictures command.  
  80.         /// </summary>  
  81.         /// <value>  
  82.         /// The show pictures command.  
  83.         /// </value>  
  84.         public ICommand ShowPicturesCommand { getprivate set; }  
  85.    
  86.         /// <summary>  
  87.         /// Gets the sava picture command.  
  88.         /// </summary>  
  89.         /// <value>  
  90.         /// The sava picture command.  
  91.         /// </value>  
  92.         public ICommand SavePictureCommand { getprivate set; }  
  93.    
  94.         /// <summary>  
  95.         /// Cameras the capeture result.  
  96.         /// </summary>  
  97.         /// <param name="photoResult">The photo result.</param>  
  98.         private async void CameraCapetureResult(Microsoft.Phone.Tasks.PhotoResult photoResult)  
  99.         {  
  100.             if (photoResult.ChosenPhoto != null)  
  101.             {  
  102.                 _mediaLibraryService.SavePicture("CimbalinoPicture",photoResult.ChosenPhoto);  
  103.             }  
  104.         }  
  105.     }  
And we should implement the PicturesViewModel as in the following.
  1. using Cimbalino.Phone.Toolkit.Services;  
  2.    
  3.     using GalaSoft.MvvmLight;  
  4.    
  5.     using Microsoft.Xna.Framework.Media;  
  6.    
  7.     /// <summary>  
  8.     /// This class contains properties that the main View can data bind to.  
  9.     /// </summary>  
  10.     public class PicturesViewModel:ViewModelBase  
  11.     {  
  12.         /// <summary>  
  13.         /// The media library service  
  14.         /// </summary>  
  15.         private readonly IMediaLibraryService _mediaLibraryService;  
  16.    
  17.         /// <summary>  
  18.         /// Initializes a new instance of the <see cref="PicturesViewModel" /> class.  
  19.         /// </summary>  
  20.         /// <param name="mediaLibraryService">The media library service.</param>  
  21.         public PicturesViewModel(IMediaLibraryService mediaLibraryService)  
  22.         {  
  23.             _mediaLibraryService = mediaLibraryService;  
  24.         }  
  25.    
  26.         /// <summary>  
  27.         /// Gets the pictures.  
  28.         /// </summary>  
  29.         /// <value>  
  30.         /// The pictures.  
  31.         /// </value>  
  32.         public PictureCollection Pictures  
  33.         {   
  34.             get  
  35.             {  
  36.                 return _mediaLibraryService.Pictures;  
  37.             }   
  38.         }  
  39.     }  
And we should implement the AlbunsViewModel as in the following:
  1. using Cimbalino.Phone.Toolkit.Services;  
  2.   
  3.    using Microsoft.Xna.Framework.Media;  
  4.   
  5.    public class AlbunsViewModel  
  6.    {  
  7.         /// <summary>  
  8.        /// The media library service  
  9.        /// </summary>  
  10.        private readonly IMediaLibraryService _mediaLibraryService;  
  11.   
  12.        /// <summary>  
  13.        /// Initializes a new instance of the <see cref="PicturesViewModel" /> class.  
  14.        /// </summary>  
  15.        /// <param name="mediaLibraryService">The media library service.</param>  
  16.        public AlbunsViewModel(IMediaLibraryService mediaLibraryService)  
  17.        {  
  18.            _mediaLibraryService = mediaLibraryService;  
  19.        }  
  20.   
  21.        /// <summary>  
  22.        /// Gets a lbuns.  
  23.        /// </summary>  
  24.        /// <value>  
  25.        /// Albuns.  
  26.        /// </value>  
  27.        public AlbumCollection Albuns   
  28.        {   
  29.            get  
  30.            {  
  31.                return _mediaLibraryService.Albums;  
  32.            }   
  33.        }  
  34.    }  
Implementing the View

The MainPage.xaml is as shown below: 
  1. <phone:PhoneApplicationPage x:Class="CimbalinoSample.MainPage"  
  2.                             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.                             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.                             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
  5.                             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
  6.                             xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"  
  7.                             xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"  
  8.                             DataContext="{Binding MainViewModel,  
  9.                                                   Source={StaticResource Locator}}"  
  10.                             FontFamily="{StaticResource PhoneFontFamilyNormal}"  
  11.                             FontSize="{StaticResource PhoneFontSizeNormal}"  
  12.                             Foreground="{StaticResource PhoneForegroundBrush}"  
  13.                             Orientation="Portrait"  
  14.                             SupportedOrientations="Portrait"  
  15.                             shell:SystemTray.IsVisible="True"  
  16.                             mc:Ignorable="d">  
  17.    
  18.     <!--  LayoutRoot is the root grid where all page content is placed  -->  
  19.     <Grid x:Name="LayoutRoot" Background="Transparent">  
  20.         <Grid.RowDefinitions>  
  21.             <RowDefinition Height="Auto" />  
  22.             <RowDefinition Height="*" />  
  23.         </Grid.RowDefinitions>  
  24.    
  25.         <!--  TitlePanel contains the name of the application and page title  -->  
  26.         <StackPanel x:Name="TitlePanel"  
  27.                     Grid.Row="0"  
  28.                     Margin="12,17,0,28">  
  29.             <TextBlock Margin="12,0"  
  30.                        Style="{StaticResource PhoneTextTitle2Style}"  
  31.                        Text="Cimbalino Sample" />  
  32.             <TextBlock Margin="9,-7,0,0"  
  33.                        Style="{StaticResource PhoneTextTitle2Style}"  
  34.                        Text="MediaLibraryService" />  
  35.         </StackPanel>  
  36.    
  37.         <!--  ContentPanel - place additional content here  -->  
  38.         <Grid x:Name="ContentPanel"  
  39.               Grid.Row="1"  
  40.               Margin="12,0,12,0">  
  41.             <TextBlock TextWrapping="Wrap">This samples has the goal to show how to use Cimbalino Windows Phone Toolkit Media Library - MediaLibraryService</TextBlock>  
  42.    
  43.             <Button Margin="0,209,0,303"  
  44.                     Command="{Binding SavePictureCommand}"  
  45.                     Content="Save Picture" />  
  46.             <Button Margin="2.985,332.896,-2.985,179.104"  
  47.                     Command="{Binding ShowPicturesCommand}"  
  48.                     Content="Show Pictures" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto" >  
  49.                 <Button.RenderTransform>  
  50.                     <CompositeTransform SkewX="1.914" TranslateX="-2.205"/>  
  51.                 </Button.RenderTransform>  
  52.             </Button>  
  53.    
  54.             <Button Margin="0,447,0,65"  
  55.                     Command="{Binding ShowAlbunsCommand}"  
  56.                     Content="Show Albuns" />  
  57.         </Grid>  
  58.     </Grid>  
  59. </phone:PhoneApplicationPage>  
The PicturesPage.xaml is as shown below:
  1. <phone:PhoneApplicationPage x:Class="CimbalinoSample.PicturesPage"  
  2.                             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.                             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.                             xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP8"  
  5.                             xmlns:converters="clr-namespace:CimbalinoSample.Converters"  
  6.                             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
  7.                             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"  
  8.                             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
  9.                             xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"  
  10.                             xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"  
  11.                             DataContext="{Binding PicturesViewModel,  
  12.                                                   Source={StaticResource Locator}}"  
  13.                             FontFamily="{StaticResource PhoneFontFamilyNormal}"  
  14.                             FontSize="{StaticResource PhoneFontSizeNormal}"  
  15.                             Foreground="{StaticResource PhoneForegroundBrush}"  
  16.                             Orientation="Portrait"  
  17.                             SupportedOrientations="Portrait"  
  18.                             shell:SystemTray.IsVisible="True"  
  19.                             mc:Ignorable="d">  
  20.     <phone:PhoneApplicationPage.Resources>  
  21.         <converters:MedialibraryConverter x:Key="medialibraryConverter" />  
  22.     </phone:PhoneApplicationPage.Resources>  
  23.     <!--  LayoutRoot is the root grid where all page content is placed  -->  
  24.     <Grid x:Name="LayoutRoot" Background="Transparent">  
  25.         <Grid.RowDefinitions>  
  26.             <RowDefinition Height="Auto" />  
  27.             <RowDefinition Height="*" />  
  28.         </Grid.RowDefinitions>  
  29.    
  30.         <!--  TitlePanel contains the name of the application and page title  -->  
  31.         <StackPanel Grid.Row="0" Margin="12,17,0,28">  
  32.             <TextBlock Margin="12,0"  
  33.                        Style="{StaticResource PhoneTextTitle2Style}"  
  34.                        Text="Cimbalino Sample" />  
  35.             <TextBlock Margin="9,-7,0,0"  
  36.                        Style="{StaticResource PhoneTextTitle2Style}"  
  37.                        Text="Pictures" />  
  38.         </StackPanel>  
  39.    
  40.         <!--  ContentPanel - place additional content here  -->  
  41.         <Grid x:Name="ContentPanel"  
  42.               Grid.Row="1"  
  43.               Margin="12,0,12,0">  
  44.             <ListBox ItemsSource="{Binding Pictures}">  
  45.                 <ListBox.ItemTemplate>  
  46.                     <DataTemplate>  
  47.                         <StackPanel>  
  48.                             <Image Height="100"  
  49.                                    Source="{Binding Converter={StaticResource medialibraryConverter}}"  
  50.                                    Stretch="Uniform" />  
  51.                             <TextBlock>  
  52.                                 Name:<Run Text="{Binding Name}" />  
  53.                             </TextBlock>  
  54.                             <TextBlock>  
  55.                                 Width:<Run Text="{Binding Width}" />  
  56.                             </TextBlock>  
  57.                             <TextBlock>  
  58.                                 Height:<Run Text="{Binding Height}" />  
  59.                             </TextBlock>  
  60.                             <TextBlock>  
  61.                                 Date:<Run Text="{Binding Date}" />  
  62.                             </TextBlock>  
  63.                             <TextBlock>  
  64.                                 Album:<Run Text="{Binding Album}" />  
  65.                                 <LineBreak />  
  66.                             </TextBlock>  
  67.                         </StackPanel>  
  68.                     </DataTemplate>  
  69.                 </ListBox.ItemTemplate>  
  70.             </ListBox>  
  71.         </Grid>  
  72.     </Grid>  
  73.    
  74. </phone:PhoneApplicationPage>  
The MediaLibraryConverter is:
  1. /// <summary>  
  2.     /// The media library converter class  
  3.     /// </summary>  
  4.     public class MedialibraryConverter : IValueConverter  
  5.     {  
  6.         /// <summary>  
  7.         /// Converts the specified value.  
  8.         /// </summary>  
  9.         /// <param name="value">The value.</param>  
  10.         /// <param name="targetType">Type of the target.</param>  
  11.         /// <param name="parameter">The parameter.</param>  
  12.         /// <param name="culture">The culture.</param>  
  13.         /// <returns></returns>  
  14.         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)  
  15.         {  
  16.            var image = (Microsoft.Xna.Framework.Media.Picture) value;  
  17.             return PictureDecoder.DecodeJpeg(image.GetImage());  
  18.         }  
  19.    
  20.         /// <summary>  
  21.         /// Converts the back.  
  22.         /// </summary>  
  23.         /// <param name="value">The value.</param>  
  24.         /// <param name="targetType">Type of the target.</param>  
  25.         /// <param name="parameter">The parameter.</param>  
  26.         /// <param name="culture">The culture.</param>  
  27.         /// <returns></returns>  
  28.         /// <exception cref="System.NotImplementedException"></exception>  
  29.         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)  
  30.         {  
  31.             throw new NotImplementedException();  
  32.         }  
  33.     }  
The AlbunsPage.xaml is as shown below:
  1. <phone:PhoneApplicationPage x:Class="CimbalinoSample.AlbunsPage"  
  2.                             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.                             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.                             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
  5.                             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
  6.                             xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"  
  7.                             xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"  
  8.                             FontFamily="{StaticResource PhoneFontFamilyNormal}"  
  9.                             FontSize="{StaticResource PhoneFontSizeNormal}"  
  10.                             Foreground="{StaticResource PhoneForegroundBrush}"  
  11.                             Orientation="Portrait"  
  12.                             DataContext="{Binding AlbunsViewModel,  
  13.                                                   Source={StaticResource Locator}}"  
  14.                             SupportedOrientations="Portrait"  
  15.                             shell:SystemTray.IsVisible="True"  
  16.                             mc:Ignorable="d">  
  17.    
  18.     <!--  LayoutRoot is the root grid where all page content is placed  -->  
  19.     <Grid x:Name="LayoutRoot" Background="Transparent">  
  20.         <Grid.RowDefinitions>  
  21.             <RowDefinition Height="Auto" />  
  22.             <RowDefinition Height="*" />  
  23.         </Grid.RowDefinitions>  
  24.    
  25.         <!--  TitlePanel contains the name of the application and page title  -->  
  26.         <StackPanel Grid.Row="0" Margin="12,17,0,28">  
  27.             <TextBlock Margin="12,0"  
  28.                        Style="{StaticResource PhoneTextTitle2Style}"  
  29.                        Text="Cimbalino Sample" />  
  30.             <TextBlock Margin="9,-7,0,0"  
  31.                        Style="{StaticResource PhoneTextTitle2Style}"  
  32.                        Text="Albuns" />  
  33.         </StackPanel>  
  34.    
  35.         <!--  ContentPanel - place additional content here  -->  
  36.         <Grid x:Name="ContentPanel"  
  37.               Grid.Row="1"  
  38.               Margin="12,0,12,0" >  
  39.             <ListBox ItemsSource="{Binding Albuns}">  
  40.                 <ListBox.ItemTemplate>  
  41.                     <DataTemplate>  
  42.                         <StackPanel>  
  43.                             <TextBlock>  
  44.                                 Name :<Run Text="{Binding Name}" />  
  45.                             </TextBlock>  
  46.                             <TextBlock>  
  47.                                 Artist: <Run Text="{Binding Artist}" />  
  48.                             </TextBlock>  
  49.                             <TextBlock>  
  50.                                 Duration :<Run Text="{Binding Duration}" />  
  51.                             </TextBlock>  
  52.                             <TextBlock>  
  53.                                 Genre :<Run Text="{Binding Genre}" />  
  54.                             </TextBlock>  
  55.                         </StackPanel>  
  56.                     </DataTemplate>  
  57.                 </ListBox.ItemTemplate>  
  58.             </ListBox>  
  59.         </Grid>  
  60.     </Grid>  
  61.    
  62. </phone:PhoneApplicationPage>