Windows Phone 8.1 FilePicker API


在 Windows Phone 8.1 中,增加了 FilePicker 的方式與文件打交道,最大的亮點在於這種方式不僅可以瀏覽手機上的文件,還可以瀏覽符合協議的應用里的文件

比如點擊 OneDrive 就會打開 OneDrive 應用:


 

(1)FileOpenPicker

FileOpenPicker 也就是選擇文件,可以設置打開單選界面或多選界面。

1)實例化 FileOpenPicker 對象,並設置 ContinuationData

private void openFileButton_Click(object sender, RoutedEventArgs e)
{
    FileOpenPicker imageOpenPicker = new FileOpenPicker();

    imageOpenPicker.FileTypeFilter.Add(".jpg");
    imageOpenPicker.FileTypeFilter.Add(".png");
    
imageOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
imageOpenPicker.ContinuationData[
"Operate"] = "OpenImage"; imageOpenPicker.PickSingleFileAndContinue(); }

FileOpenPicker 可以設置 FileTypeFilter,方便文件的瀏覽;還可以設置選擇界面的開始目錄(SuggestedStartLocation)。

因為在打開選擇文件的界面后當前應用會掛起,所以需要 ContinuationData 來記錄一些信息,以保證當應用恢復時能夠保持之前的信息。

 

2)重寫 App.xaml.cs 的 OnActivated 方法

當用戶選擇了文件之后會返回到之前的應用,這時需要重寫 OnActivated 方法讓應用跳轉到指定頁面,並傳遞用戶選擇的文件。

protected override void OnActivated(IActivatedEventArgs args)
{
    if( args is FileOpenPickerContinuationEventArgs )
    {
        Frame rootFrame = Window.Current.Content as Frame;

        if( rootFrame == null )
        {
            rootFrame = new Frame();

            rootFrame.CacheSize = 1;

            Window.Current.Content = rootFrame;
        }

        if( rootFrame.Content == null )
        {
            if( rootFrame.ContentTransitions != null )
            {
                this.transitions = new TransitionCollection();
                foreach( var c in rootFrame.ContentTransitions )
                {
                    this.transitions.Add(c);
                }
            }

            rootFrame.ContentTransitions = null;
            rootFrame.Navigated += this.RootFrame_FirstNavigated;

            if( !rootFrame.Navigate(typeof(MainPage)) )
            {
                throw new Exception("Failed to create first page");
            }
        }

        if( !rootFrame.Navigate(typeof(MainPage)) )
        {
            throw new Exception("Failed to create target page");
        }

        MainPage targetPage = rootFrame.Content as MainPage;
        targetPage.FilePickerEventArgs = (FileOpenPickerContinuationEventArgs)args;

        Window.Current.Activate();
    }
}

首先是要判斷之前的行為是不是 FileOpenPicker 引起的,然后獲取 Frame 並跳轉到指定頁面,將包含用戶選擇文件的信息 args 傳遞到指定頁面中。

 

3)添加 FileOpenPickerContinuationEventArgs 屬性和 ContinuFileOpenPicker 方法

當應用將 args 傳遞到頁面去后,剩下的就是處理文件了:

private FileOpenPickerContinuationEventArgs filePickerEventArgs;
public FileOpenPickerContinuationEventArgs FilePickerEventArgs
{
    get { return filePickerEventArgs; }
    set
    {
        filePickerEventArgs = value;
        ContinuFileOpenPicker(filePickerEventArgs);
    }
}

private async void ContinuFileOpenPicker(FileOpenPickerContinuationEventArgs args)
{
    if( args.ContinuationData["Operate"] as string == "OpenImage" && args.Files != null && args.Files.Count > 0 )
    {
        StorageFile file = args.Files[0];

        BitmapImage image = new BitmapImage();
        await image.SetSourceAsync(await file.OpenAsync(FileAccessMode.Read));

        myImage.Source = image;
    }
}

 

(2)AccessCache

AccessCache 也就是指對用戶選擇文件或文件夾的緩存,包括 MostRecentlyUsedList 和 FutureAccessList。

MostRecentlyUsedList 可以保存 25 項,並會根據用戶使用情況自動排序,當新的進來后超過 25 項了則會自動將最舊的刪除。

FutureAccessList 則可以保存 1000 項,但不會自動排序,需要開發者自行管理。

保存方法:

private async void ContinuFileOpenPicker(FileOpenPickerContinuationEventArgs args)
{
    if( args.ContinuationData["Image"] as string == "OpenImage" && args.Files != null && args.Files.Count > 0 )
    {
        StorageFile file = args.Files[0];

        BitmapImage image = new BitmapImage();
        await image.SetSourceAsync(await file.OpenAsync(FileAccessMode.Read));

        myImage.Source = image;

        StorageApplicationPermissions.MostRecentlyUsedList.Add(file, "20140528");
        StorageApplicationPermissions.FutureAccessList.Add(file, "20140528");
    }
}

讀取方法:

private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
    var mruList = StorageApplicationPermissions.MostRecentlyUsedList.Entries; foreach( var item in mruList )
    {
        StorageFile file = await StorageApplicationPermissions.MostRecentlyUsedList.GetFileAsync(item.Token);

        BitmapImage image = new BitmapImage();
        await image.SetSourceAsync(await file.OpenAsync(FileAccessMode.Read));

        Image img = new Image();
        img.Source = image;
        img.Stretch = Stretch.Uniform;
        img.Margin = new Thickness(0, 0, 0, 10);
        imagesStackPanel.Children.Add(img);
    }
}

開發者可以靈活使用這兩個列表,方便用戶瀏覽最近使用過的文件。

 

(3)FileSavePicker

既然有 OpenPicker,自然就有 SavePicker。

FileSavePicker 的使用方法與 FileOpenPicker 非常相似。

1)實例化 FileSavePicker 對象,並設置 ContinuationData

private void saveButton_Click(object sender, RoutedEventArgs e)
{
    FileSavePicker imageSavePicker = new FileSavePicker();

    imageSavePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
    imageSavePicker.SuggestedFileName = "Test";
    imageSavePicker.FileTypeChoices.Add("Txt", new List<string>() { ".txt" });

    imageSavePicker.ContinuationData["Txt"] = "SaveTxt";
    imageSavePicker.PickSaveFileAndContinue();
}

實例化 FileSavePicker 對象后,設置 FileName 和 FileType。

當用戶選擇了某個文件夾后,系統就會在該文件夾中新建一個該 FileName 和 FileType 的文件,並將該文件放到 FileSavePickerContinuationEventArgs 中。

2)重寫 App.xaml.cs 的 OnActivated 方法

與 FileOpenPicker 一樣,同樣需要重寫 OnActivated 方法,這次要檢查的 args 類型為 FileSavePickerContinuationEventArgs:

protected override void OnActivated(IActivatedEventArgs args)
{
    if( args is FileSavePickerContinuationEventArgs )
    {
        Frame rootFrame = Window.Current.Content as Frame;

        // 不要在窗口已包含內容時重復應用程序初始化,
        // 只需確保窗口處於活動狀態
        if( rootFrame == null )
        {
            // 創建要充當導航上下文的框架,並導航到第一頁
            rootFrame = new Frame();

            // TODO: 將此值更改為適合您的應用程序的緩存大小
            rootFrame.CacheSize = 1;

            if( args.PreviousExecutionState == ApplicationExecutionState.Terminated )
            {
                // TODO: 從之前掛起的應用程序加載狀態
            }

            // 將框架放在當前窗口中
            Window.Current.Content = rootFrame;
        }

        if( rootFrame.Content == null )
        {
            // 刪除用於啟動的旋轉門導航。
            if( rootFrame.ContentTransitions != null )
            {
                this.transitions = new TransitionCollection();
                foreach( var c in rootFrame.ContentTransitions )
                {
                    this.transitions.Add(c);
                }
            }

            rootFrame.ContentTransitions = null;
            rootFrame.Navigated += this.RootFrame_FirstNavigated;

            // 當導航堆棧尚未還原時,導航到第一頁,
            // 並通過將所需信息作為導航參數傳入來配置
            // 新頁面
            if( !rootFrame.Navigate(typeof(MainPage)) )
            {
                throw new Exception("Failed to create initial page");
            }
        }

        if( !rootFrame.Navigate(typeof(MainPage)) )
        {
            throw new Exception("Failed to create target page");
        }

        MainPage targetPage = rootFrame.Content as MainPage;
        targetPage.SavePickerArgs = (FileSavePickerContinuationEventArgs)args;

        // 確保當前窗口處於活動狀態
        Window.Current.Activate();
    }
}
OnActivated

 

3)添加 FileSavePickerContinuationEventArgs 屬性和 ContinuFileSavePicker 方法

最后在 ContinuFileSavePicker 方法中對要保存的文件進行操作:

private FileSavePickerContinuationEventArgs savePickerArgs;
public FileSavePickerContinuationEventArgs SavePickerArgs
{
    get { return savePickerArgs; }
    set
    {
        savePickerArgs = value;
        ContinuFileSavePicker(savePickerArgs);
    }
}

private async void ContinuFileSavePicker(FileSavePickerContinuationEventArgs args)
{
    if( args.ContinuationData["Txt"] as string == "SaveTxt" && args.File != null )
    {
        StorageFile txt = args.File; await FileIO.WriteTextAsync(txt, "1224677");
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM