Welcome

首页 / 软件开发 / .NET编程技术 / Windows 8 Store Apps学习(39) 契约: Share Contract

Windows 8 Store Apps学习(39) 契约: Share Contract2013-12-06 cnblogs webabcd介绍

重新想象 Windows 8 Store Apps 之 契约

Share Contract - 右侧边栏称之为 Charm,其 中的“共享”称之为 Share Contract

示例

1、演示如何开发共享源

Contracts/ShareContract/ShareSource.xaml

<Pagex:Class="XamlDemo.Contracts.ShareContract.ShareSource"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="using:XamlDemo.Contracts.ShareContract"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"><Grid Background="Transparent"><StackPanel Margin="120 0 0 0"><TextBlock Name="lblMsg" FontSize="14.667" /><Button Content="Share Text" Click="Button_Click_1" Margin="0 10 0 0" /><Button Content="Share Link" Click="Button_Click_1" Margin="0 10 0 0" /><Button Content="Share Image" Click="Button_Click_1" Margin="0 10 0 0" /><Button Content="Share File" Click="Button_Click_1" Margin="0 10 0 0" /><Button Content="Share Html" Click="Button_Click_1" Margin="0 10 0 0" /><Button Content="Share Custom Data" Click="Button_Click_1" Margin="0 10 0 0" /><Button Content="Share With Deferral" Click="Button_Click_1" Margin="0 10 0 0" /></StackPanel></Grid></Page>
Contracts/ShareContract/ShareSource.xaml.cs

/* * Share Contract - 右侧边栏称之为 Charm,其中的“共享”称之为 Share Contract ** 本例演示如何开发共享源 * 共享源 - 提供共享数据的 app * 共享目标 - 接收并处理共享数据的 app * 共享面板 - 点击“共享”后出来的,包含了一堆共享目标的面板 ** DataTransferManager - 共享数据管理器 * GetForCurrentView() - 返回当前窗口关联的 DataTransferManager 对象 * ShowShareUI() -弹出共享面板,以开始共享操作 * DataRequested - 共享操作开始时(即弹出共享面板后)所触发的事件,事件参数为 DataTransferManager 和 DataRequestedEventArgs * TargetApplicationChosen - 选中了共享面板上的某个共享目标时所触发的事件,事件参数为 DataTransferManager 和 TargetApplicationChosenEventArgs ** TargetApplicationChosenEventArgs - TargetApplicationChosen 的事件参数 * ApplicationName - 选中的共享目标的名称 ** DataRequestedEventArgs - DataRequested 的事件参数 * Request - 返回 DataRequest 类型的数据 ** DataRequest - 一个对象,其包括了共享的内容和错误提示 * FailWithDisplayText() - 指定当共享操作失败时,需要在共享面板上显示的提示信息 * Data - 需要共享的内容,返回 DataPackage 对象 ** DataPackage - 共享内容(注:复制到剪切板的内容也是通过此对象来封装) * Properties - 返回 DataPackagePropertySetView 对象 * Properties.Title - 共享数据的标题 * Properties.Description - 共享数据的描述 * Properties.Thumbnail - 共享数据的缩略图 * Properties.FileTypes - 获取共享数据中包含的文件类型 * SetText(), SetUri(), SetHtmlFormat(), SetRtf(), SetBitmap(), SetStorageItems(), SetData(), SetDataProvider() - 设置需要共享的各种格式的数据,详细用法见下面的相关 demo(注:一个 DataPackage 可以有多种不同格式的数据) * ResourceMap - IDictionary<string, RandomAccessStreamReference> 类型,共享 html 时如果其中包含了本地资源的引用(如引用了本地图片),则需要通过 ResourceMap 传递 * GetView() - 返回 DataPackageView 对象,其相当于 DataPackage 的一个只读副本,详细说明见 ShareTarget.xaml.cs * 另:WebView.DataTransferPackage 会返回用户选中的内容的 DataPackage 对象,以便分享浏览器内的 html 内容 ** 异步共享: * 1、DataPackage 通过 SetDataProvider() 传递数据,其对应的委托的参数为一个 DataProviderRequest 类型的数据 * 2、DataProviderRequest.GetDeferral() 用于获取 DataProviderDeferral 对象以开始异步处理,然后通过 DataProviderDeferral.Complete() 通知 DataPackage 已经完成了异步操作 */using System;using System.Collections.Generic;using System.Threading.Tasks;using Windows.ApplicationModel.DataTransfer;using Windows.Storage;using Windows.Storage.Pickers;using Windows.Storage.Streams;using Windows.UI.ViewManagement;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Navigation;using System.Linq;using Windows.Graphics.Imaging;namespace XamlDemo.Contracts.ShareContract{public sealed partial class ShareSource : Page{// 当前需要分享的内容的类型private string _shareType = "Share Text";// 需要分享的文件集合private IReadOnlyList<StorageFile> _selectedFiles;public ShareSource(){this.InitializeComponent();}protected override void OnNavigatedTo(NavigationEventArgs e){// 初始化 DataTransferManagerDataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();dataTransferManager.DataRequested += dataTransferManager_DataRequested;dataTransferManager.TargetApplicationChosen += dataTransferManager_TargetApplicationChosen;}void dataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args){// 共享操作开始时(即弹出共享面板后),根据需要分享的内容的类型执行指定的方法switch (_shareType){case "Share Text":ShareText(sender, args);break;case "Share Link":ShareLink(sender, args);break;case "Share Image":ShareImage(sender, args);break;case "Share File":ShareFile(sender, args);break;case "Share With Deferral":ShareWithDeferral(sender, args);break;case "Share Html":ShareHtml(sender, args);break;case "Share Custom Data":ShareCustomData(sender, args);break;default:break;}// 共享操作失败时,在共享面板上显示的提示信息// args.Request.FailWithDisplayText("共享操作失败"); }void dataTransferManager_TargetApplicationChosen(DataTransferManager sender, TargetApplicationChosenEventArgs args){// 显示用户需要与其共享内容的应用程序的名称lblMsg.Text = "共享给:" + args.ApplicationName;}private async void Button_Click_1(object sender, RoutedEventArgs e){_shareType = (sender as Button).Content.ToString();// 如果需要共享文件,则提示用户选择文件if (_shareType == "Share Image" || _shareType == "Share File" || _shareType == "Share With Deferral"){bool unsnapped = ((ApplicationView.Value != ApplicationViewState.Snapped) || ApplicationView.TryUnsnap());if (unsnapped){FileOpenPicker filePicker = new FileOpenPicker{ViewMode = PickerViewMode.List,SuggestedStartLocation = PickerLocationId.PicturesLibrary,FileTypeFilter = { "*" }// FileTypeFilter = { ".jpg", ".png", ".bmp", ".gif", ".tif" }};_selectedFiles = await filePicker.PickMultipleFilesAsync();if (_selectedFiles.Count > 0){// 弹出共享面板,以开始共享操作DataTransferManager.ShowShareUI();}}}else{// 弹出共享面板,以开始共享操作DataTransferManager.ShowShareUI();}}// 共享文本的 Demoprivate void ShareText(DataTransferManager dtm, DataRequestedEventArgs args){DataPackage dataPackage = args.Request.Data;dataPackage.Properties.Title = "Title";dataPackage.Properties.Description = "Description";dataPackage.SetText("需要分享的详细内容");}// 共享超链的 Demoprivate void ShareLink(DataTransferManager dtm, DataRequestedEventArgs args){DataPackage dataPackage = args.Request.Data;dataPackage.Properties.Title = "Title";dataPackage.Properties.Description = "Description";dataPackage.SetUri(new Uri("http://webabcd.cnblogs.com"));}// 共享图片的 Demo(关于如何为分享的图片减肥请参见本例的“异步共享的 Demo”)private void ShareImage(DataTransferManager dtm, DataRequestedEventArgs args){DataPackage dataPackage = args.Request.Data;dataPackage.Properties.Title = "Title";dataPackage.Properties.Description = "Description";// 分享选中的所有文件中的第一个文件(假设其是图片)RandomAccessStreamReference imageStreamRef = RandomAccessStreamReference.CreateFromFile(_selectedFiles.First());dataPackage.Properties.Thumbnail = imageStreamRef;dataPackage.SetBitmap(imageStreamRef);}// 共享文件的 Demoprivate void ShareFile(DataTransferManager dtm, DataRequestedEventArgs args){DataPackage dataPackage = args.Request.Data;dataPackage.Properties.Title = "Title";dataPackage.Properties.Description = "Description";dataPackage.SetStorageItems(_selectedFiles);}// 共享 html 的 Demoprivate void ShareHtml(DataTransferManager dtm, DataRequestedEventArgs args){string localImage = "ms-appx:///Assets/Logo.png";string htmlExample = "<p><b>webabcd</b><img src="" + localImage + "" /></p>";// 为 html 添加共享所需的必要的标头,以保证可以正常进行 html 的共享操作string htmlFormat = HtmlFormatHelper.CreateHtmlFormat(htmlExample);DataPackage dataPackage = args.Request.Data;dataPackage.Properties.Title = "Title";dataPackage.Properties.Description = "Description";dataPackage.SetHtmlFormat(htmlFormat);// 设置本地图像数据(如果需要共享的 html 包含本地图像,则只能通过这种方法共享之)RandomAccessStreamReference streamRef = RandomAccessStreamReference.CreateFromUri(new Uri(localImage));dataPackage.ResourceMap[localImage] = streamRef;/* * 以下演示如何共享 WebView 中的被用户选中的 html * 具体可参见:Controls/WebView/Share.xaml * DataPackage dataPackage = WebView.DataTransferPackage;DataPackageView dataPackageView = dataPackage.GetView();if ((dataPackageView != null) && (dataPackageView.AvailableFormats.Count > 0)){dataPackage.Properties.Title = "Title";dataPackage.Properties.Description = "Description";args.Request.Data = dataPackage;}*/}// 共享自定义数据的 Demoprivate void ShareCustomData(DataTransferManager dtm, DataRequestedEventArgs args){DataPackage dataPackage = args.Request.Data;dataPackage.Properties.Title = "Title";dataPackage.Properties.Description = "Description";// 指定需要分享的自定义数据,第一个参数是自定义数据的格式 id(注:标准格式 id 在 Windows.ApplicationModel.DataTransfer.StandardDataFormats 枚举)// 要让自定义数据可以正常分享,需要在 Package.appxmanifest 中的“共享目标”声明中对自定义格式 id 做相应的配置,以及在 SourceTarget 对自定义格式 id 做相应的处理dataPackage.SetData("http://webabcd/sharedemo", "自定义数据");}// 异步共享的 Demo(在共享内容需要较长时间才能计算出来的场景下,应该使用异步共享)private void ShareWithDeferral(DataTransferManager dtm, DataRequestedEventArgs args){DataPackage dataPackage = args.Request.Data;dataPackage.Properties.Title = "Title";dataPackage.Properties.Description = "Description";dataPackage.Properties.Thumbnail = RandomAccessStreamReference.CreateFromFile(_selectedFiles.First());// 通过委托来提供共享数据,当用户点击了共享目标后会调用此委托,即不马上提供共享数据,而是等到用户点击了共享目标后再异步准备数据dataPackage.SetDataProvider(StandardDataFormats.Bitmap, providerRequest => this.OnDeferredImageRequestedHandler(providerRequest, _selectedFiles.First()));}// 用户点击了共享目标后会调用此方法private async void OnDeferredImageRequestedHandler(DataProviderRequest providerRequest, StorageFile imageFile){// 获取 DataProviderDeferral,以开始异步处理,即在此之后允许调用 await 方法DataProviderDeferral deferral = providerRequest.GetDeferral();InMemoryRandomAccessStream inMemoryStream = new InMemoryRandomAccessStream();try{// 将用户选中的图片缩小一倍,然后再共享IRandomAccessStream imageStream = await imageFile.OpenAsync(FileAccessMode.Read);BitmapDecoder imageDecoder = await BitmapDecoder.CreateAsync(imageStream);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();// 停 3 秒,以模拟长时间任务await Task.Delay(3000);providerRequest.SetData(RandomAccessStreamReference.CreateFromStream(inMemoryStream));}finally{// 通知 DataPackage 已经完成了共享数据的准备deferral.Complete();}}}}