共享数据

本文将说明如何在桌面或通用 Windows 平台 (UWP) 应用中支持“共享”合约。 “共享”合约是一种在应用之间快速共享文本、链接、照片和视频等数据的简便方法。 例如,用户可能希望使用社交网络应用与其好友共享网页,或者将链接保存在笔记应用中以供日后参考。

注意

本文中的代码示例来自 UWP 应用。 桌面应用应使用 IDataTransferManagerInterop。 有关详细信息和代码示例,请参阅显示依赖于 CoreWindow 的 WINRT UI 对象。 另请参阅 WPF 共享内容源应用示例

设置事件处理程序

添加一个 DataRequested 事件处理程序,以便在用户调用共享时调用。 这种情况在用户点击应用程序中的控件(例如按钮或应用程序栏命令)发生,或者在特定场景(例如,如果用户完成关卡并获得高分)下自动发生。

DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();
dataTransferManager.DataRequested += DataTransferManager_DataRequested;

当发生 DataRequested 事件时,你的应用程序会收到一个 DataRequest 对象。 其中包含一个 DataPackage,可以使用它来提供用户想要共享的内容。 必须提供要共享的标题和数据。 说明是选填的,但建议填写它。

DataRequest request = args.Request;

选择数据

可以共享各种类型的数据,包括:

  • 纯文本
  • 统一资源标识符 (URI)
  • HTML
  • 带格式文本
  • 位图
  • 文件
  • 自定义开发人员定义的数据

DataPackage 对象可以包含一个或多个这些格式(以任意组合形式)。 下面的示例演示了共享文本。

request.Data.SetText("Hello world!");

设置属性

打包数据以供共享时,可以提供各种属性,以提供有关所共享内容的附加信息。 这些属性有助于目标应用程序改善用户体验。 例如,当用户与多个应用共享内容时,说明会有所帮助。 共享图像或网页链接时添加缩略图可为用户提供视觉参考。 有关详细信息,请参阅 DataPackagePropertySet

警告

除标题之外的所有属性都是可选的。 标题属性是必需的,必须设置。

request.Data.Properties.Title = "Share Example";
request.Data.Properties.Description = "A demonstration on how to share";

启动共享 UI

用于共享的 UI 由系统提供。 若要启动它,请调用 ShowShareUI 方法。

DataTransferManager.ShowShareUI();

处理错误

在大多数情况下,共享内容的过程非常简单。 不过,事事都有例外。 例如,应用可能要求用户选择要共享的内容,但用户没有选择任何内容。 若要处理这种情况,请使用 FailWithDisplayText 方法,该方法会在出现问题时向用户显示一条消息。

延迟共享与代理

有时,立即准备用户想要共享的数据可能没有意义。 例如,如果你的应用支持以多种不同的可能格式发送大型图像文件,那么在用户做出选择之前创建所有这些图像的效率会很低。

为了解决此问题,DataPackage 可以包含委托,即接收应用程序请求数据时调用的函数。 建议在用户想要共享的数据属于资源密集型数据时使用代理。

async void OnDeferredImageRequestedHandler(DataProviderRequest request)
{
    // Provide updated bitmap data using delayed rendering
    if (this.imageStream != null)
    {
        DataProviderDeferral deferral = request.GetDeferral();
        InMemoryRandomAccessStream inMemoryStream = new InMemoryRandomAccessStream();

        // Decode the image.
        BitmapDecoder imageDecoder = await BitmapDecoder.CreateAsync(this.imageStream);

        // Re-encode the image at 50% width and height.
        BitmapEncoder imageEncoder = await BitmapEncoder.CreateForTranscodingAsync(inMemoryStream, imageDecoder);
        imageEncoder.BitmapTransform.ScaledWidth = (uint)(imageDecoder.OrientedPixelWidth * 0.5);
        imageEncoder.BitmapTransform.ScaledHeight = (uint)(imageDecoder.OrientedPixelHeight * 0.5);
        await imageEncoder.FlushAsync();

        request.SetData(RandomAccessStreamReference.CreateFromStream(inMemoryStream));
        deferral.Complete();
    }
}

另请参阅