首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Windows 8 Store Apps 共用合約完整實作:共用來源、共用目標與 QuickLink

     編輯:關於.NET

前言

共用合約是 Windows 8 特有的應用間資料交換機制。使用者從任意應用呼叫「共用」Charm,選擇目標應用接收資料。本文完整實作共用來源(提供資料)、共用目標(接收處理)、QuickLink(快捷共用)與應用啟動整合。

架構角色與核心類別

角色核心類別關鍵流程
共用來源DataTransferManager、DataPackageDataRequested 事件 → 填充 DataPackage → 系統顯示共用面板
共用目標ShareOperation、DataPackageViewApp.xaml.cs OnShareTargetActivated → 解析 DataPackageView → ReportCompleted
QuickLinkQuickLink目標端 ReportCompleted(quickLink) → 來源面板顯示快捷項 → 再次啟動攜帶 QuickLinkId

共用來源實作:提供多格式資料

初始化 DataTransferManager


protected override void OnNavigatedTo(NavigationEventArgs e) {
    var dtm = DataTransferManager.GetForCurrentView();
    dtm.DataRequested += OnDataRequested;
    dtm.TargetApplicationChosen += OnTargetChosen;
}

private void OnTargetChosen(DataTransferManager sender, TargetApplicationChosenEventArgs args) {
    lblStatus.Text = $"共用給: {args.ApplicationName}";
}

DataRequested 事件處理:依類型填充 DataPackage


private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args) {
    var request = args.Request;
    var data = request.Data;
    data.Properties.Title = "標題";
    data.Properties.Description = "描述";
    
    switch (_shareType) {
        case "Share Text":
            data.SetText("需要分享的詳細內容");
            break;
        case "Share Link":
            data.SetUri(new Uri("https://webabcd.cnblogs.com"));
            break;
        case "Share Image":
            var imgRef = RandomAccessStreamReference.CreateFromFile(_selectedFiles.First());
            data.Properties.Thumbnail = imgRef;
            data.SetBitmap(imgRef);
            break;
        case "Share File":
            data.SetStorageItems(_selectedFiles);
            break;
        case "Share Html":
            string html = "

webabcd

"; data.SetHtmlFormat(HtmlFormatHelper.CreateHtmlFormat(html)); data.ResourceMap["ms-appx:///Assets/Logo.png"] = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/Logo.png")); break; case "Share Custom Data": data.SetData("https://webabcd/sharedemo", "自訂資料內容"); break; case "Share With Deferral": data.Properties.Thumbnail = RandomAccessStreamReference.CreateFromFile(_selectedFiles.First()); data.SetDataProvider(StandardDataFormats.Bitmap, OnDeferredImageRequested); break; } }

異步共用:SetDataProvider 延遲提供資料

資料生成耗時(如大圖壓縮)時,使用 SetDataProvider 註冊提供者,使用者選擇目標後才執行:


private async void OnDeferredImageRequested(DataProviderRequest request, StorageFile imageFile) {
    var deferral = request.GetDeferral();
    try {
        using (var stream = await imageFile.OpenAsync(FileAccessMode.Read)) {
            var decoder = await BitmapDecoder.CreateAsync(stream);
            var memStream = new InMemoryRandomAccessStream();
            var encoder = await BitmapEncoder.CreateForTranscodingAsync(memStream, decoder);
            encoder.BitmapTransform.ScaledWidth = (uint)(decoder.OrientedPixelWidth * 0.5);
            encoder.BitmapTransform.ScaledHeight = (uint)(decoder.OrientedPixelHeight * 0.5);
            await encoder.FlushAsync();
            
            // 模擬長時間處理
            await Task.Delay(3000);
            
            request.SetData(RandomAccessStreamReference.CreateFromStream(memStream));
        }
    } finally {
        deferral.Complete();
    }
}

共用目標實作:接收與處理共用資料

App.xaml.cs 啟動進入點


protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args) {
    var rootFrame = new Frame();
    rootFrame.Navigate(typeof(ShareTargetPage), args);
    Window.Current.Content = rootFrame;
    Window.Current.Activate();
}

Package.appxmanifest 宣告

在「宣告」頁籤新增「共用目標」,勾選支援的資料格式:文字、URI、HTML、位圖、儲存項目、自訂格式(需填入格式識別碼如 https://webabcd/sharedemo)。

ShareTargetPage 解析資料


protected async override void OnNavigatedTo(NavigationEventArgs e) {
    var args = (ShareTargetActivatedEventArgs)e.Parameter;
    _shareOperation = args.ShareOperation;
    
    await Task.Run(async () => {
        // 基本屬性
        ShowMessage($"QuickLinkId: {_shareOperation.QuickLinkId}");
        ShowMessage($"Title: {_shareOperation.Data.Properties.Title}");
        ShowMessage($"Description: {_shareOperation.Data.Properties.Description}");
        await ShowThumbnail(_shareOperation.Data.Properties.Thumbnail);
        
        // 依格式解析
        var data = _shareOperation.Data;
        if (data.Contains(StandardDataFormats.Text)) {
            ShowMessage($"Text: {await data.GetTextAsync()}");
        }
        if (data.Contains(StandardDataFormats.Uri)) {
            ShowMessage($"Uri: {(await data.GetUriAsync()).AbsoluteUri}");
        }
        if (data.Contains(StandardDataFormats.Bitmap)) {
            await ShowBitmap(await data.GetBitmapAsync());
        }
        if (data.Contains(StandardDataFormats.Html)) {
            ShowMessage($"Html: {await data.GetHtmlFormatAsync()}");
            var resourceMap = await data.GetResourceMapAsync(); // 取得本地資源引用
        }
        if (data.Contains(StandardDataFormats.StorageItems)) {
            foreach (var item in await data.GetStorageItemsAsync()) {
                ShowMessage($"File: {item.Path}");
            }
        }
        if (data.Contains("https://webabcd/sharedemo")) {
            ShowMessage($"Custom: {await data.GetTextAsync("https://webabcd/sharedemo")}");
        }
    });
}

private async void OnCompleteClick(object sender, RoutedEventArgs e) {
    var quickLink = new QuickLink {
        Id = "預定義資料,避免使用者重複輸入",
        Title = "快捷共用標題",
        Thumbnail = RandomAccessStreamReference.CreateFromFile(
            await Package.Current.InstalledLocation.GetFileAsync("Assets\\Logo.png")),
        SupportedFileTypes = { "*" },
        SupportedDataFormats = { 
            StandardDataFormats.Text, StandardDataFormats.Uri, 
            StandardDataFormats.Bitmap, StandardDataFormats.StorageItems,
            StandardDataFormats.Html, "https://webabcd/sharedemo" 
        }
    };
    _shareOperation.ReportCompleted(quickLink); // 完成並新增 QuickLink
}

QuickLink:共用目標的快捷方式

QuickLink 讓使用者一鍵重複共用給相同目標(如固定郵件收件者、社群帳號)。生命週期:

  1. 目標端 ReportCompleted(quickLink) 時建立
  2. 來源端共用面板上方顯示 QuickLink 圖示
  3. 使用者點擊 QuickLink → 系統啟動目標應用,ShareOperation.QuickLinkId 攜帶預定義 Id
  4. 目標端解析 QuickLinkId 直接執行動作(如自動填入收件者)
  5. 使用者可移除 QuickLink,目標端可呼叫 RemoveThisQuickLink()

資料格式支援矩陣

格式StandardDataFormats來源 Set 方法目標 Get 方法備註
文字TextSetTextGetTextAsync最基礎格式
連結UriSetUriGetUriAsync單一 URI
HTMLHtmlSetHtmlFormatGetHtmlFormatAsync需 HtmlFormatHelper 封裝,ResourceMap 傳遞本地圖片
位圖BitmapSetBitmapGetBitmapAsyncRandomAccessStreamReference
檔案StorageItemsSetStorageItemsGetStorageItemsAsyncIReadOnlyList
RTFRtfSetRtfGetRtfAsync富文本格式
自訂自訂字串SetDataGetDataAsync需雙方約定,Manifest 宣告

最佳實踐與避坑

  1. 來源端: 僅在 DataRequested 事件中填充 DataPackage,不可預先建立(資料可能過時)。
  2. 來源端: 大資料(圖片、檔案)務必使用 SetDataProvider 延遲渲染,避免共用面板開啟延遲。
  3. 來源端: HTML 含本地圖片時,必須同時設定 ResourceMap,否則目標端無法解析圖片。
  4. 目標端: OnNavigatedTo 中務必 await 所有 GetXxxAsync,切勿同步阻塞。
  5. 目標端: 完成共用務必呼叫 ReportCompleted()(可選 QuickLink),否則共用面板不會關閉。
  6. 目標端: 長時間處理時定期呼叫 ReportStarted()、ReportDataRetrieved()、ReportSubmittedBackgroundTask() 讓系統優化資源。
  7. Manifest: 共用目標支援的格式必須在 Manifest 完整宣告,缺漏會導致該格式不顯示在共用面板。
  8. QuickLink: SupportedDataFormats/SupportedFileTypes 需與目標端實際支援一致,不匹配則不顯示。

共用來源與剪貼簿的關係

DataPackage 同時服務於共用合約與剪貼簿。同一份資料準備邏輯可同時支援「複製」與「共用」兩種使用者意圖,只需分別呼叫 Clipboard.SetContent() 與 DataTransferManager.ShowShareUI()。

完整實作共用合約,能讓你的應用無縫融入 Windows 8 的應用生態系統,成為資料流動的來源或目的地。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved