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

Windows 8 Store Apps 開發實戰 (26):打造自訂檔案選取器與儲存選取器

     編輯:關於.NET

前言:重新想像檔案選取體驗

在 Windows 8 Store Apps 中,檔案選取器不只是單純的對話框,更是一種可擴展的合約機制。透過實作「檔案開啟選取器」與「檔案儲存選取器」提供者,開發者能讓自家 App 成為其他應用程式的檔案來源或儲存目標,打造整合度極高的使用者體驗。本篇將深入解析 FileOpenPickerUI 與 FileSavePickerUI 的核心概念,並透過完整程式碼示範如何從零建立自訂選取器。

核心架構解析

FileOpenPickerUI - 自訂檔案開啟選取器

當使用者在其他 App 中呼叫 FileOpenPicker 並選擇您的提供者時,系統會啟動您的 App 並傳遞 FileOpenPickerActivatedEventArgs。透過此參數取得 FileOpenPickerUI 物件,即可控制選取器介面:

  • AllowedFileTypes:唯讀,呼叫端指定的允許檔案類型
  • SelectionMode:單選或多選模式
  • Title:選取器標題列文字
  • AddFile(id, file):將檔案加入選取清單,回傳 AddFileResult 指示成功、已存在或不被允許
  • FileRemoved / Closing 事件:監聽使用者移除檔案或關閉選取器

FileSavePickerUI - 自訂檔案儲存選取器

儲存選取器的運作模式不同:使用者指定檔名與位置後按下「儲存」,系統會觸發 TargetFileRequested 事件。您必須在事件處理常式中建立目標檔案(通常在 ApplicationData.Current.LocalFolder),並指派給 args.Request.TargetFile。因涉及非同步 I/O,務必呼叫 GetDeferral() 取得延遲物件,完成後呼叫 Complete()。

實作範例:自訂開啟選取器

1. 宣告合約

在 Package.appxmanifest 的「宣告」頁籤新增「檔案開啟選取器」,支援的檔案類型至少要包含一項(如 .png、.jpg 或 *)。

2. 啟動進入點

// App.xaml.cs
protected override void OnFileOpenPickerActivated(FileOpenPickerActivatedEventArgs args)
{
    var rootFrame = new Frame();
    rootFrame.Navigate(typeof(XamlDemo.Picker.MyOpenPicker), args);
    Window.Current.Content = rootFrame;
    Window.Current.Activate();
}

3. 頁面邏輯

// MyOpenPicker.xaml.cs 關鍵片段
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    var args = (FileOpenPickerActivatedEventArgs)e.Parameter;
    _fileOpenPickerUI = args.FileOpenPickerUI;
    _fileOpenPickerUI.Title = "自訂檔案開啟選取器";
}

private async void btnPickLocalFile_Click_1(object sender, RoutedEventArgs e)
{
    // 從安裝目錄取得範例圖片
    StorageFile file = await Package.Current.InstalledLocation.GetFileAsync(@"Assets\Logo.png");
    AddFileResult result = _fileOpenPickerUI.AddFile("myFile", file);
    lblMsg.Text = "選取的檔案: " + file.Name + "\nAddFileResult: " + result;
}

private async void btnPickRemoteFile_Click_1(object sender, RoutedEventArgs e)
{
    // 建立串流式遠端檔案(副檔名需符合 FileTypeFilter)
    Uri uri = new Uri("https://images.cnblogs.com/mvpteam.gif", UriKind.Absolute);
    StorageFile file = await StorageFile.CreateStreamedFileFromUriAsync(
        "mvp.gif", uri, RandomAccessStreamReference.CreateFromUri(uri));
    AddFileResult result = _fileOpenPickerUI.AddFile("myFile", file);
    lblMsg.Text = "選取的檔案: " + file.Name + "\nAddFileResult: " + result;
}

實作範例:自訂儲存選取器

1. 宣告合約

在 Package.appxmanifest 新增「檔案儲存選取器」宣告,同樣需指定支援的檔案類型。

2. 啟動進入點

// App.xaml.cs
protected override void OnFileSavePickerActivated(FileSavePickerActivatedEventArgs args)
{
    var rootFrame = new Frame();
    rootFrame.Navigate(typeof(XamlDemo.Picker.MySavePicker), args);
    Window.Current.Content = rootFrame;
    Window.Current.Activate();
}

3. 頁面邏輯

// MySavePicker.xaml.cs 關鍵片段
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    var args = (FileSavePickerActivatedEventArgs)e.Parameter;
    _fileSavePickerUI = args.FileSavePickerUI;
    _fileSavePickerUI.Title = "自訂檔案儲存選取器";
    _fileSavePickerUI.TargetFileRequested += _fileSavePickerUI_TargetFileRequested;
}

private async void _fileSavePickerUI_TargetFileRequested(FileSavePickerUI sender, TargetFileRequestedEventArgs args)
{
    var deferral = args.Request.GetDeferral();
    try
    {
        // 在本地資料夾建立唯一檔名的空白檔案
        StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(
            sender.FileName, CreationCollisionOption.GenerateUniqueName);
        args.Request.TargetFile = file;
    }
    catch (Exception ex)
    {
        await OutputMessage(ex.ToString());
    }
    finally
    {
        deferral.Complete();
    }
}

關鍵提醒

  1. 副檔名一致性:AddFile 傳入的檔案副檔名必須符合呼叫端 FileOpenPicker.FileTypeFilter 設定,否則會被拒絕。
  2. 啟動模式:自訂選取器屬於「啟動合約」,App 必須正確處理 OnFileOpenPickerActivated / OnFileSavePickerActivated,並在導航時將 args 傳遞給頁面。
  3. 遠端檔案:使用 CreateStreamedFileFromUriAsync 可避免先下載再上傳,直接串流傳遞給呼叫端。
  4. 非同步完成:儲存選取器的 TargetFileRequested 必須使用 GetDeferral() 模式,確保非同步作業完成後再通知系統。
  5. 完整程式碼下載

    原始碼完整包(含所有範例專案)

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