鉴于之前我有一篇博客讲访问手机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 ------ 文档类型集合,其实就可以看作是文件格式的过滤器,只筛选我们想要看的格式的文件
搞定了属性,有了一个大概的了解,就可以动手了
对于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