介紹
重新想象 Windows 8 Store Apps 之 契約
Share Contract - 右側邊欄稱之為 Charm,其 中的“共用”稱之為 Share Contract
樣本
1、示範如何開發共用源
Contracts/ShareContract/ShareSource.xaml
<Page x: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) { // 初始化 DataTransferManager DataTransferManager 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(); } } // 共用文本的 Demo private void ShareText(DataTransferManager dtm, DataRequestedEventArgs args) { DataPackage dataPackage = args.Request.Data; dataPackage.Properties.Title = "Title"; dataPackage.Properties.Description = "Description"; dataPackage.SetText("需要分享的詳細內容"); } // 共用超鏈的 Demo private 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); } // 共用檔案的 Demo private void ShareFile(DataTransferManager dtm, DataRequestedEventArgs args) { DataPackage dataPackage = args.Request.Data; dataPackage.Properties.Title = "Title"; dataPackage.Properties.Description = "Description"; dataPackage.SetStorageItems(_selectedFiles); } // 共用 html 的 Demo private 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; } */ } // 共用自訂資料的 Demo private 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(); } } }}