天天看點

Win8和Windows Phone 8.1資源橋梁:FileOpenPicker

鑒于之前我有一篇部落格講通路手機SD卡中的檔案的,那個是原先知道了檔案的路徑或者說知道了檔案放在那裡,是以

通過代碼直接擷取,當然是行得通的。但是很多情況下我們不知道我們要的檔案在SD卡的哪裡,我們要慢慢逐層查

找,然後選中後才行。這時就需要FileOpenPicker了。

通路手機SD卡檔案的部落格位址: Windows Phone8.1中SD卡檔案的讀取寫入方法彙總

打個比方,一張自拍照,大部分女生呢要用美圖秀秀啊等美圖軟體修的美美的才能上傳到各個社交網站上去。當我們

要完成這個需求,我們的步驟是什麼呢?

第一種呢,當然可以直接打開相冊,找到自拍照,選擇編輯方式,連結到美圖秀秀軟體打開即可(這種連結應用的方

式也很常用,有必要掌握,這篇部落格不做介紹)

第二種呢,性子急的是直接打開美圖秀秀,然後美圖裡有個按鈕讓你選擇你手機相冊中的具體那張圖檔,這時跳出來

的讓你再手機中逐層查找圖檔,最終選擇到自拍照的過程就是FileOpenPicker來實作的。

微軟官方連結:FileOpenPicker

好了,知道了為什麼需要這個東西,那麼該了解下FilePicker的一些常見的屬性:

(很多屬性按字面意思來思考即可,并不是很難了解。其實看微軟官方連結更好更詳細,很有幫助)

1.ViewMode(PickerViewMode類型) ------   呈現項目的視圖模式  List/Thumbnail  項的清單/縮略圖像集

2.SuggestedStartLocation(PickerLoactionId類型)  --------- 呈現給我們的檔案的起始位置 documents/videos

/pictures/musicLibary  downloads   desktop    homeGroup

3.CommitButtonText  ------  選擇檔案後我們要按的确認按鈕上面的文字

4.SettingIdentifier   -------   用到多個FileOpenPicker時給單個FileOpenPicker作的辨別以示區分

注意:以上屬性在Windows Phone 8.1中無效

5.FileTypeFilter  ------  文檔類型集合,其實就可以看作是檔案格式的過濾器,隻篩選我們想要看的格式的檔案

搞定了屬性,有了一個大概的了解,就可以動手了

當然以下兩個平台上,應該都是需要在VS的清單檔案中功能和申明頁籤上添加對應的功能。申明中應該加檔案打開

選擇器,具體類似流程參照我的通路手機SD卡檔案的部落格,在上面已經貼對外連結接了。

對于Windows 8及8.1的平台,兩者可能有一些小不同,但是基本都是一緻的,版本的更新沒有改動多少。

直接上僞代碼:

FileOpenPicker picker = new FileOpenPicker();
//設定打開的顯示模式
picker.ViewMode = PickerViewMode.List;
//起始打開文檔顯示的視窗,這邊選擇的是桌面
picker.SuggestedStartLocation = PickerLocationId.Desktop;
//其實就是過濾的作用,規定你要打開的是.txt檔案
picker.FileTypeFilter.Add(".txt");
// PickMultipleFilesAsync是選取多個檔案,
// PickSingleFileAsync選取單個檔案
StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
	//傳回的是檔案名
	txtTitle.Text = file.Name;
	//傳回的是檔案路徑
	//txtTitle.Text = file.Path;
	var stream = await file.OpenStreamForReadAsync();
	StreamReader sr = new StreamReader(stream);
	//這個是在你的.txt文本是以ANSI(國标)編碼的時候要規定encoding
	//StreamReader sr = new StreamReader(stream,Encoding.GetEncoding("GB2312"));
	string txt = await sr.ReadToEndAsync();
	txtContent.Text = txt;
}
           

而Windows Phone平台的就不一樣了,遠比Windows來的麻煩些,WP8與WP8.1間的版本疊代也是有一些不同的

那麼Windows Phone麻煩在哪裡呢。

其一是手機存在着當FileOpenPicker起作用的時候,應用被挂起了,當FileOpenPicker選擇完成後,應用又要恢複過

來的情況,是以這個時候重寫OnActivated事件和ContinueFileOpenPicker函數就顯得關鍵和必要了

其二是Windows平台中的FileOpenPicker的選取單個或者多個檔案的屬性對應着PickerSingleFileAsync()和

PickMultipleFilesAsync(),雖說是異步的,就一個async和一個await就搞定了。而Windows Phone平台就隻能

PickSingleFileAndContinue()和PickMultipleFilesAndContinue(),這個就是配合第一點的,處理起來麻煩。

總之一點,麻煩就麻煩在如何在調用檔案選取器後繼續運作 Windows Phone 應用。下面給出微軟的解釋和解決方

案,大家看一下基本上就明白了,如果還是覺得太淩亂了,我的也可以将就看看了。

官方的解釋和解決方案:如何在調用檔案選取器後繼續運作 Windows Phone 應用 (XAML)

麻煩歸麻煩,問題終究要解決的。而解決此問題分三大步,至于每一步的原因上面都做了解答。

首先要在App.xaml.cs中重寫OnActivated()事件

protected override void OnActivated(IActivatedEventArgs args)
{
    if(args is FileOpenPickerContinuationEventArgs)
    {
        Frame rootFrame = Window.Current.Content as Frame;
        if(!rootFrame.Navigate(typeof(RepresentBook)))
        {
            throw new Exception("Failed to create target page");
        }

        var page = rootFrame.Content as RepresentBook;
        page.FileOpenPickerEvent = (FileOpenPickerContinuationEventArgs)args;
    }
    Window.Current.Activate();
}
           

其次在對應的頁面的.cs中執行個體化FileOpenPicker對象,把該有的屬性都設定好

private void findBtn_Click(object sender, RoutedEventArgs e)
{
    //清空錯誤資訊
    txtTip.Text = "";

    //執行個體化FileOpenPicker對象-檔案選取器
    FileOpenPicker picker = new FileOpenPicker();
    //設定打開的顯示模式,這個在WP8.1上不起作用,而在Win8.1上還是有用的
    //picker.ViewMode = PickerViewMode.Thumbnail;
    //其實打開文檔顯示的視窗,這個在WP8.1上不起作用,而在Win8.1上還是有用的
    //picker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
    //規定打開的檔案格式
    picker.FileTypeFilter.Add(".txt");
    //利用ContinuationData 來記錄一些資訊,以保證應用恢複時能擷取應用挂起的資訊
    picker.ContinuationData["Operation"] = "Text";
    //送出按鈕上顯示的文本,在WP8.1上不起作用,在Win8.1上還是有用的
    //picker.CommitButtonText = "找書";
    //設定可選取單個檔案還是多個檔案
    picker.PickSingleFileAndContinue();
}
           

最後利用FileOpenPicker的頁面處理函數ContinueFileOpenPicker處理傳回的資料

這個首先要給頁面這個類定義一個屬性,就是get,set嘛

private FileOpenPickerContinuationEventArgs _fileOpenPickerEventArgs = null;

public FileOpenPickerContinuationEventArgs FileOpenPickerEvent
{
    get { return _fileOpenPickerEventArgs; }
    set
    {
        _fileOpenPickerEventArgs = value;
        ContinueFileOpenPicker(_fileOpenPickerEventArgs);
    }
}
           

然後利用ContinueFileOpenPicker函數處理傳回資料

public void ContinueFileOpenPicker(FileOpenPickerContinuationEventArgs args)
{
    if ((args.ContinuationData["Operation"] as string) == "Text" && args.Files != null && args.Files.Count > 0)
    {
        StorageFile file = args.Files[0];

        List<BookInfo> bookinfo = new List<BookInfo>();

        Random random = new Random();
        int ran = random.Next(1, 6);
        string imguri = "Assets/Images/" + ran + ".jpg";

        int length = localSettings.Values.Count+1;
        string key = "booklist" + length.ToString();
        if (!localSettings.Containers.ContainsKey(key))
        {
            ApplicationDataCompositeValue composite = new ApplicationDataCompositeValue();
            composite["bookimg"] = imguri;
            composite["bookname"] = file.Name;
            composite["bookpath"] = file.Path;
            
            if(localSettings.Values.Count==0)
            {
                localSettings.Values[key] = composite;
            }
            else
            {
                for (int i = 1; i < localSettings.Values.Count + 1; i++)
                {
                    ApplicationDataCompositeValue composite2 = new ApplicationDataCompositeValue();
                    composite2 = (ApplicationDataCompositeValue)localSettings.Values["booklist" + i.ToString()];
                    if (composite2["bookname"].ToString()==file.Name)
                    {
                        txtTip.Text = "清單中已存在此書籍!";
                    }
                }
                if(txtTip.Text=="")
                {
                    localSettings.Values[key] = composite;
                }
            }
            
        }   
        if(localSettings.Values.Count!=0)
        {
            for (int i = 1; i < localSettings.Values.Count+1;i++ )
            {
                ApplicationDataCompositeValue composite = new ApplicationDataCompositeValue();
                composite = (ApplicationDataCompositeValue)localSettings.Values["booklist" + i.ToString()];
                bookinfo.Add(new BookInfo { bookImg = composite["bookimg"].ToString(), bookName = composite["bookname"].ToString(), bookPath = composite["bookpath"].ToString() });
            }
            listbox.ItemsSource = bookinfo;
        }
        
    }
}
           

以上都是僞代碼,大家弄清楚思想即可。

推薦連結:

程式設計小夢:windows phone 8.1開發:檔案選擇器FileOpenPicker



繼續閱讀