How to use the photo picker from a Direct3D app for Windows Phone 8

[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]

This topic describes how to display the photo picker from a Windows Phone Direct3D app so that a user can select a photo from the phone’s pictures library. The photo is returned to your app as a StorageFile object.

The photo picker is launched using the PickSingleFileAsync()()() method. In Windows 8, this method can be used to pick any type of file, but in Windows Phone, only images can be selected. Because of this, there are a few properties of the FileOpenPicker object that must be set properly or the picker will not launch. The following table shows these properties and their required values.

Property

Required value

ViewMode

PickerViewMode::Thumbnail

SuggestedStartLocation

PickerLocationId::PicturesLibrary

FileTypeFilter

“*”

If the user navigates away from your app after the picker operation has completed and your app is suspended, your app can resume the picking operation to retrieve the user-selected file by calling ResumePickSingleFileAsync()()(). On Windows Phone, the PickSingleFileAsync()()() method has an optional ID parameter. If your app uses multiple photo pickers, this app-defined ID string can be used to identify which picker was launched before your app was suspended.

Using the photo picker

  1. Create a new Windows Phone Direct3D app. This example assumes that you name the project NativePhotoPicker.

  2. Add the declaration for an event handler for the Completed event to the NativePhotoPicker.h header file. This event is called when the photo picking operation is completed. The type of the result for this operation is a reference to a StorageFile that will contain the returned image.

        void PickSingleFileCompletedHandler(Windows::Foundation::IAsyncOperation<Windows::Storage::StorageFile^>^ operation, Windows::Foundation::AsyncStatus status);
    
  3. Declare a member variable that will contain an app-defined ID for the currently active picker. If your app uses multiple pickers, this variable will help you determine which one has returned. If your app only uses a single picker, you can skip this step.

        Platform::String^ m_pickerID;
    
  4. Add using statements to reference the Windows.Storage and Windows.Storage.Pickers namespaces to the top of the NativePhotoPicker.cpp.

  5. Create a new instance of the FileOpenPicker class. As discussed earlier in this topic, there are required values for view mode, start location, and file type filter of FileOpenPicker that must be set or the picking operation will fail.

    Call PickSingleFileAsync()()() to begin the picking operation. In this example, the overload of this method that takes a single string is used to demonstrate how to track which picking operation is in progress if the app is suspended and then resumed during the operation. If your app only uses one picker, you can skip this step.

    Finally, hook up the event handler for the Completed()()() event of the IAsyncOperation object returned by PickSingleFileAsync()()().

    In this example, the code to launch the photo picker is put into the OnPointerPressed method included in the Direct3D app project template. This handler will be called if you touch anywhere on the screen.

    void NativePhotoPicker::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
    {
        // Insert event handling here
        FileOpenPicker^ fileOpenPicker = ref new FileOpenPicker();
        fileOpenPicker->ViewMode = PickerViewMode::Thumbnail;
        fileOpenPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
        fileOpenPicker->FileTypeFilter->Append("*");
    
        m_pickerID = "ID_12345";
        IAsyncOperation<StorageFile^>^ pickSingleFileOperation = fileOpenPicker->PickSingleFileAsync(m_pickerID);
    
        pickSingleFileOperation->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>(this, &NativePhotoPicker::PickSingleFileCompletedHandler);
    }
    
  6. Add the implementation of the Completed()()() event handler. Call GetResults()()() to obtain a StorageFile object that contains the image data. If you are using multiple pickers, you can check your member variable that contains the picker ID to see which one fired this event.

    void NativePhotoPicker::PickSingleFileCompletedHandler(IAsyncOperation<Windows::Storage::StorageFile^>^ operation, AsyncStatus status)
    {
        StorageFile^ file = operation->GetResults();
    
        if(m_pickerID == "ID_12345")
        {
            // Do something with the file.
        }
    }
    
  7. Add code to handle app activation and deactivation. In Windows Phone, it is possible for an app to be suspended and then reactivated during a picker operation. If the operation has not been completed by the user when the app is suspended, the picker simply auto-dismisses as if the user cancelled the operation. However, if the user completes the picker operation but the app is suspended before the Completed()()() event is raised, the IActivatedEventArgs passed into your app’s Activated event will have a Kind property with the value of ActivationKind::PickerReturned. If this is the case, you can cast the args object as an IPickerReturnedActivatedEventArgs object and get the PickerOperationId()()() property if you specified an ID when you launched the picker. Then you can simply call ResumePickSingleFileAsync()()() to continue the picking operation and hook up the same event handler you used earlier to handle the results.

    void NativePhotoPicker::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
    {
        CoreWindow::GetForCurrentThread()->Activate();
    
        if(args->Kind == ActivationKind::PickerReturned)
        {
            m_pickerID = ((IPickerReturnedActivatedEventArgs^)args)->PickerOperationId;
    
            IAsyncOperation<StorageFile^>^ pickSingleFileOperation = FileOpenPicker::ResumePickSingleFileAsync();
            pickSingleFileOperation->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>(this, &NativePhotoPicker::PickSingleFileCompletedHandler);
        }
    }
    

Testing the picker with app suspension and activation

  • During app development, it is important to test whether your app handles app suspension and activation properly. In Visual Studio, on the Project menu, click [Project Name] Properties. In the Property Pages dialog, under Configuration Properties, click Debugging. Change the value of Tombstone upon deactivation to Yes. Now, when you launch your app with debugging enabled and then launch the photo picker, your app will automatically be suspended. When you use the Back button to return to your app, the code in the Activated event handler will run and call your custom event handler with the selected image.