How to share an image (XAML)
Perhaps the most common content users want to share are images and photos. Here, we'll show you how to share a single image from your app.
The code in this section focuses on using SetBitmap to share a bitmap image. Often, users share images that are represented as files. As a result, we recommend that your app also support StorageItems, which can be a collection of files. We describe how to support StorageItems in How to share files.
What you need to know
Technologies
Prerequisites
- You should be familiar with Visual Studio and its templates.
- You should be familiar with developing in C#/C++.
- You should understand how to get files and other data, such as by using FileOpenPicker. You can learn more in Quickstart: Accessing files with file pickers.
Instructions
Step 1: Adding the DataTransfer namespace
You need to add the right namespaces to your app so you can create and process the objects related to sharing. At a minimum, you should add the Windows.ApplicationModel.DataTransfer namespace:
using Windows.ApplicationModel.DataTransfer;
using namespace Windows::ApplicationModel::DataTransfer;
This namespace has all you need for basic sharing. Remember, though, if you want to share content such as images or files, you'll need to add those namespaces as well. Here's a list of the namespaces you might need:
- Windows.Storage. Needed for working with StorageFile and other objects.
- Windows.Storage.Pickers. Used to open the file picker so users can select images and files.
- Windows.Storage.Streams. Often used when sharing images, files, and custom-formatted data.
- Windows.Graphics.Imaging. Useful if you need to modify images before sharing them.
Step 2: Get the DataTransferManager object
The DataTransferManager object is the starting point for any sharing operation.
DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();
DataTransferManager^ dataTransferManager = DataTransferManager::GetForCurrentView();
Step 3: Add an event handler for the DataRequested event
Add a DataRequested event handler to fire when the user wants to invoke Share. In a Windows Store app, this occurs automatically when the user invokes the Share charm. If you're developing for Windows Phone, there is no built-in Share charm, so you'll need to add a control for the user to tap and trigger the handler.
dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager,
DataRequestedEventArgs>(this.ShareImageHandler);
auto dataRequestedToken = dataTransferManager->DataRequested +=
ref new TypedEventHandler<DataTransferManager^, DataRequestedEventArgs^>(
this, &MainPage:: ShareImageHandler);
Step 4: Get a DataRequest object
When a DataRequested event occurs, your app receives a DataRequest object. This object contains a DataPackage that you can use to provide the content that the user wants to share.
DataRequest request = e.Request;
DataRequest^ request = e->Request;
Step 5: Set the title and description properties
The title property is mandatory and must be set.
// The title is mandatory
request.Data.Properties.Title = "Share Image Example";
request.Data.Properties.Description = "Demonstrates how to share an image.";
// The title is mandatory
request->Data->Properties->Title = "Share Image Example";
request->Data->Properties->Description = "Demonstrates how to share an image.";
Step 6: Add a thumbnail to the DataPackage
We recommend that you always add a thumbnail image any time you're sharing an image.
request.Data.Properties.Thumbnail = RandomAccessStreamReference.CreateFromFile(thumbnailFile);
request->Data->Properties->Thumbnail = RandomAccessStreamReference::CreateFromFile(thumbnailFile);
Check out the Thumbnail reference topic to learn about our recommended file sizes for thumbnail images.
Step 7: Add the image as a bitmap to the DataPackage
To share an image, use the SetBitmap method. This method expects the image to be of the RandomAccessStreamReference type. To share multiple images, share them as StorageItems instead. We describe how to support StorageItems in How to share files. This helps to ensure that the user can choose from the largest number of apps when they share the image.
request.Data.SetBitmap(RandomAccessStreamReference.CreateFromFile(imageFile));
request->Data->SetBitmap(RandomAccessStreamReference::CreateFromFile(imageFile));
Remarks
If your app needs to use an asynchronous operation to prepare the image or the thumbnail, you’ll need to use the deferral pattern. We show how to do this in How to make asynchronous calls in your DataRequested handler.
If your app takes more than 200 milliseconds to get the image ready, you need to use a delegate function to share it. We show you how to do this in How to support pull operations.
Example
Here's an example that sets an image for a user to share. For a more complete example, check out our code gallery sample.
private void RegisterForShare()
{
DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();
dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager,
DataRequestedEventArgs>(this.ShareImageHandler);
}
private async void ShareImageHandler(DataTransferManager sender,
DataRequestedEventArgs e)
{
DataRequest request = e.Request;
request.Data.Properties.Title = "Share Image Example";
request.Data.Properties.Description = "Demonstrates how to share an image.";
// Because we are making async calls in the DataRequested event handler,
// we need to get the deferral first.
DataRequestDeferral deferral = request.GetDeferral();
// Make sure we always call Complete on the deferral.
try
{
StorageFile thumbnailFile =
await Package.Current.InstalledLocation.GetFileAsync("Assets\\SmallLogo.png");
request.Data.Properties.Thumbnail =
RandomAccessStreamReference.CreateFromFile(thumbnailFile);
StorageFile imageFile =
await Package.Current.InstalledLocation.GetFileAsync("Assets\\Logo.png");
request.Data.SetBitmap(RandomAccessStreamReference.CreateFromFile(imageFile));
}
finally
{
deferral.Complete();
}
}
void MainPage::RegisterForShare()
{
DataTransferManager^ dataTransferManager = DataTransferManager::GetForCurrentView();
auto dataRequestedToken = dataTransferManager->DataRequested +=
ref new TypedEventHandler<DataTransferManager^, DataRequestedEventArgs^>(
this, &MainPage::ShareImageHandler);
}
void MainPage::ShareImageHandler(DataTransferManager^ sender, DataRequestedEventArgs^ e)
{
DataRequest^ request = e->Request;
request->Data->Properties->Title = "Share Image Example";
request->Data->Properties->Description = "Demonstrates how to share an image.";
// Because we are making async calls in the DataRequested event handler,
// we need to get the deferral first.
DataRequestDeferral^ deferral = request->GetDeferral();
create_task(Package::Current->InstalledLocation->GetFileAsync("Assets\\SmallLogo.png")).then(
[this, request](StorageFile^ thumbnailFile)
{
request->Data->Properties->Thumbnail =
RandomAccessStreamReference::CreateFromFile(thumbnailFile);
return Package::Current->InstalledLocation->GetFileAsync("Assets\\Logo.png");
}).then([this, request, deferral](task<StorageFile^> getImageFileTask)
{
try
{
auto imageFile = getImageFileTask.get();
request->Data->SetBitmap(RandomAccessStreamReference::CreateFromFile(imageFile));
deferral->Complete();
}
catch (Exception^ ex)
{
// Calling FailWithDisplayText() also calls Complete the deferral.
request->FailWithDisplayText(ex->Message);
}
});
Related topics
Sharing content source app sample
Windows.ApplicationModel.DataTransfer