本文介绍如何在桌面或通用 Windows 平台(UWP)应用中支持共享协定。 共享合约是一种在应用之间快速共享数据(如文本、链接、照片和视频)的简单方法。 例如,用户可能想要使用社交网络应用与好友共享网页,或者将链接保存在笔记应用中供以后参考。
注释
本文中的代码示例来自 UWP 应用。 桌面应用应使用 IDataTransferManagerInterop。 有关详细信息和代码示例,请参阅 显示依赖于 CoreWindow 的 WinRT UI 对象。
还可以参考 Windows 应用中的 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();
}
}