Using Picker Controls in Your Windows Phone Apps

Introduction

In many applications, there is a need to let the user select a file/folder to support a particular task.

Windows Phone 8.1 has baked in support to allow users to select files by using the FileOpenPicker control. If there is a need to select a folder (for example, when we need to ask the user to select the folder where the data needs to be saved), Windows Phone 8.1 offers the FolderPicker control that lets users select a folder. Both controls are housed in the Windows.Storage.Pickers namespace.

FileOpenPicker Control Basics

The FileOpenPicker control is an UI element that users can use to choose and select files. It supports choosing a single file as well as multiple files. The FileOpenPicker class supports selecting a single file as well as multiple files.

To select a single file, we need to call the PickSingleFileAndContinue() API on the FileOpenPicker class. The FileOpenPicker control also supports providing a suggested start location, and a file filter if you want to restrict the selection to a specific extension. To select multiple files, we call the PickMultipleFilesAndContinue() API.

FolderPicker Control Basics

The FolderPicker control works like FileOpenPicker; however, this control is meant to select folders. Like the FileOpenPicker control, the FolderPicker control also supports providing a suggested start location.

Hands On

Create a new Visual Studio 2013 project of type Visual C# -> Store Apps -> Windows Phone Apps by using the Blank App (Windows Phone) template.

FilePicker1
Figure 1: Setting up the blank app

Once our project is created, add three Button controls to MainPage.xaml, as shown in Figure 2.

FilePicker2
Figure 2: Adding the Button controls

The XAML for this change is:

<Page
   x_Class="WPPickerDemo.MainPage"
   
   xmlns_local="using:WPPickerDemo"
   xmlns_d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns_mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   mc_Ignorable="d"
   Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

   <Grid>
      <Button x_Name="buttonMultipleFile"
         Content="Multiple Files Selector"
         HorizontalAlignment="Left" Margin="122,107,0,0"
         VerticalAlignment="Top" Width="206"/>
      <Button x_Name="buttonSingleFile"
         Content="Single File Selector"
         HorizontalAlignment="Left" Margin="122,40,0,0"
         VerticalAlignment="Top" Width="206"/>
      <Button x_Name="buttonFolder"
         Content="Folder Selector" HorizontalAlignment="Left"
         Margin="122,175,0,0" VerticalAlignment="Top"
         Width="155"/>

   </Grid>
</Page>

Selecting a file/folder is an async event that requires a lot of complicated programming. The official sample from Microsoft requires a lot of lifecycle management handling of application events. In this walkthrough, we will use a simpler method that was shared on the MSDN forums by an enthusiast. In this approach, we will create an extension method on the picker controls and invoke these methods from async APIs. For this, we need a couple of local variables that will represent the files/folder that were selected.

//App.xaml.cs
public sealed partial class App : Application
   {
      static IReadOnlyList<StorageFile> filePickerFiles;
      static StorageFolder folderPickerFolder;
      private TransitionCollection transitions;

Next, we update App.xaml.cs to override the OnActivated event to trap the Activated event.

protected async override void OnActivated(IActivatedEventArgs args)
   {
      base.OnActivated(args);
      if (args.Kind == ActivationKind.PickFileContinuation)
      {
         var newargs = args as FileOpenPickerContinuationEventArgs;
         filePickerFiles = newargs.Files;
         if (filePickerFiles == null)
            filePickerFiles = new List<StorageFile>();
         }
         else if (args.Kind == ActivationKind.PickFolderContinuation)
         {
            var newargs = args as FolderPickerContinuationEventArgs;
            folderPickerFolder = newargs.Folder;
         }
      }

We then implement the helper methods that invoke the picker class APIs.

public static async Task<IReadOnlyList<StorageFile>>
MultipleFileSelectorHelper(Windows.Storage.Pickers.FileOpenPicker filePicker)
   {
      filePickerFiles = null;

      Boolean pickerOpen = false;

      while (filePickerFiles == null)
      {
         if (!pickerOpen)
         {
            pickerOpen = true;
            filePicker.PickMultipleFilesAndContinue();
         }
         await Task.Delay(new TimeSpan(0, 0, 0, 0, 200));
      }
      return filePickerFiles;
   }
   public static async Task<IReadOnlyList<StorageFile>>
      SingleFileSelectorHelper(Windows.Storage.Pickers.FileOpenPicker filePicker)
   {
      filePickerFiles = null;
      Boolean pickerOpen = false;
      while (filePickerFiles == null)
      {
         if (!pickerOpen)
         {
            pickerOpen = true;
            filePicker.PickSingleFileAndContinue();
         }
         await Task.Delay(new TimeSpan(0, 0, 0, 0, 200));
      }
      return filePickerFiles;
   }
   public static async Task<StorageFolder>
      FolderSelectorHelper(Windows.Storage.Pickers.FolderPicker folderPicker)
   {
      folderPickerFolder = null;
      Boolean pickerOpen = false;
      while (folderPickerFolder == null)
      {
         if (!pickerOpen)
         {
            pickerOpen = true;
            folderPicker.PickFolderAndContinue();
         }
         await Task.Delay(new TimeSpan(0, 0, 0, 0, 200));
      }
      return folderPickerFolder;
   }

Next, we implement the extension methods on the picker control.

static class ExtensionMethods
   {
      public static Task<IReadOnlyList<StorageFile>>
         PickMultipleFilesWP8Async(this Windows.Storage.Pickers.FileOpenPicker filePicker)
      {
         return App.MultipleFileSelectorHelper(filePicker);
      }

      public static Task<IReadOnlyList<StorageFile>>
         PickSingleFileWP8Async(this Windows.Storage.Pickers.FileOpenPicker filePicker)
      {
         return App.SingleFileSelectorHelper(filePicker);
      }

      public static Task<StorageFolder>
         PickSingleFolderWP8Async(this Windows.Storage.Pickers.FolderPicker folderPicker)
      {
         return App.FolderSelectorHelper(folderPicker);
      }
   }

Finally, we implement the click event handlers on the buttons we added on MainPage.xaml.

private async void buttontryMultipleFile_Click(object sender, RoutedEventArgs e)
   {
      Windows.Storage.Pickers.FileOpenPicker picker =
         new Windows.Storage.Pickers.FileOpenPicker();
      picker.SuggestedStartLocation =
         Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
      picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
      picker.FileTypeFilter.Clear();
      picker.FileTypeFilter.Add(".jpg");
      picker.FileTypeFilter.Add(".bmp");
      picker.FileTypeFilter.Add(".jpeg");
      picker.FileTypeFilter.Add(".png");
      IReadOnlyList<StorageFile> storageFiles = null;
      storageFiles = await picker.PickMultipleFilesWP8Async();
      foreach (var file in storageFiles)
      {
         MessageDialog filename = new MessageDialog(file.DisplayName);
         await filename.ShowAsync();
      }
   }
   private async void buttonSingleFile_Click(object sender, RoutedEventArgs e)
   {
      Windows.Storage.Pickers.FileOpenPicker picker =
         new Windows.Storage.Pickers.FileOpenPicker();
      picker.SuggestedStartLocation =
         Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
      picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
      picker.FileTypeFilter.Clear();
      picker.FileTypeFilter.Add(".jpg");
      picker.FileTypeFilter.Add(".bmp");
      picker.FileTypeFilter.Add(".jpeg");
      picker.FileTypeFilter.Add(".png");
      IReadOnlyList<StorageFile> storageFiles = null;
      storageFiles = await picker.PickSingleFileWP8Async();
      foreach (var file in storageFiles)
      {
         MessageDialog filename = new MessageDialog(file.DisplayName);
         await filename.ShowAsync();
      }
   }
   private async void buttonFolder_Click(object sender, RoutedEventArgs e)
   {
      Windows.Storage.Pickers.FolderPicker picker =
         new Windows.Storage.Pickers.FolderPicker();
      picker.SuggestedStartLocation =
         Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
      picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
      picker.FileTypeFilter.Clear();
      StorageFolder storageFolder = await picker.PickSingleFolderWP8Async();
      MessageDialog folderName = new MessageDialog(storageFolder.DisplayName);
      await folderName.ShowAsync();
   }

Our application is now ready. We now can run this application and see the picker control in action.

Summary

In this article, we learned how to use picker controls in the Windows Phone application. If you want to check out the sample code, you can download it from this article.

About the Author

Vipul Patel is a technology geek based in Seattle. He can be reached at vipul.patel@hotmail.com. You can visit his LinkedIn profile at https://www.linkedin.com/pub/vipul-patel/6/675/508.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read