图解使用Win8Api进行Metro风格的程序开发二----使用文件选择器访问和保存文件

我们紧接着上篇,这篇将介绍如何使用文件选择器访问和保存文件

-----------------------------------我是华丽的分割线-----------------------------------------

此示例演示用户如何使用文件选择器选择您的应用程序文件和文件夹,
根据用户指定的名称,文件类型和文件保存的位置。
这个示例使用Windows.Storage.Pickers API。

本篇将介绍如下四个方面:

a)让用户选择一个文件

b)让用户选择多个文件

c)让用户选择一个文件夹

d)让用户保存文件和指定的名称,文件类型和/或保存位置

我们的创建的步骤如下:

1)为了组织文件方便,我们先建一个文件夹FilePicker

2)向文件夹中添加如下四个文件:

  PickAFolder.xaml,PickASinglePhoto.xaml,PickMultipleFiles.xaml,SaveAFile.xaml

  创建方式如图:

3)此时的解决方案结构如下:

4)向我们的DataSource添加导航所需要的信息

  修改我们的SampleDataSource.cs文件中的SampleDataSource类中的代码,

  代码如下: 

View Code
    public sealed class SampleDataSource
    {
        private static SampleDataSource _sampleDataSource = new SampleDataSource();

        private ObservableCollection<SampleDataGroup> _allGroups = new ObservableCollection<SampleDataGroup>();
        public ObservableCollection<SampleDataGroup> AllGroups
        {
            get { return this._allGroups; }
        }

        public static IEnumerable<SampleDataGroup> GetGroups(string uniqueId)
        {
            if (!uniqueId.Equals("AllGroups")) throw new ArgumentException("Only 'AllGroups' is supported as a collection of groups");

            return _sampleDataSource.AllGroups;
        }

        public static SampleDataGroup GetGroup(string uniqueId)
        {
            // Simple linear search is acceptable for small data sets
            var matches = _sampleDataSource.AllGroups.Where((group) => group.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }

        public static SampleDataItem GetItem(string uniqueId)
        {
            // Simple linear search is acceptable for small data sets
            var matches = _sampleDataSource.AllGroups.SelectMany(group => group.Items).Where((item) => item.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }

        public SampleDataSource()
        {
            var group1 = new SampleDataGroup("FilePicker",
              "Use Windows.Storage.Pickers API",
              "Access and save files using the file picker",
              "Assets/FilePicker.jpg",
              "");
            group1.Items.Add(new SampleDataItem("FilePicker-PickASinglePhoto",
                    "Pick a single photo",
                    "only one file can selected,file type is jpg,jpeg,png",
                    "Assets/FilePicker.jpg",
                    "only one file can selected ",
                    "",
                    group1,
                    typeof(PickASinglePhoto)));
            group1.Items.Add(new SampleDataItem("FilePicker-PickMultipleFiles",
                    "Pick multiple files",
                    "you can pick multiple files",
                    "Assets/FilePicker.jpg",
                    "pick multiple files",
                    "",
                    group1,
                    typeof(PickMultipleFiles)));
            group1.Items.Add(new SampleDataItem("FilePicker-PickAFolder",
                    "Pick a folder",
                    "you can pick a folder",
                    "Assets/FilePicker.jpg",
                    "Pick a folder",
                    "",
                    group1,
                    typeof(PickAFolder)));
            group1.Items.Add(new SampleDataItem("FilePicker-SaveAFile",
                    "Save a file",
                    "you can save a file",
                    "Assets/FilePicker.jpg",
                    "Save a file",
                    "",
                    group1,
                    typeof(SaveAFile)));
            this.AllGroups.Add(group1);
        }
    }

 

5)我们的导航这样就做好了,效果图:

点击,出现如下图片:

6)我们开始我们的任务:让用户选择一个文件

使用的FileOpenPicker的PickSingleFileAsync方法来调用一个文件选择器窗口,
让用户选择一个单一的文件。

修改PickASinglePhoto.xaml的代码:

View Code
    <Grid x:Name="LayoutRoot" Background="{StaticResource ApplicationPageBackgroundThemeBrush}" HorizontalAlignment="Left" VerticalAlignment="Top">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid x:Name="Input" Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>

            <TextBlock Grid.Row="0" TextWrapping="Wrap" Style="{StaticResource SubheaderTextStyle}" HorizontalAlignment="Left" >
                Prompt the user to pick a single photo.
            </TextBlock>
            <Button Grid.Row="1" x:Name="PickAFileButton" Content="Pick photo" Margin="0,10,10,0"/>
        </Grid>

        <Grid x:Name="Output" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">
            <TextBlock x:Name="OutputTextBlock" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap" />
        </Grid>
    </Grid>

 

修改后台代码:

View Code
    public sealed partial class PickASinglePhoto : Page
    {
        public PickASinglePhoto()
        {
            this.InitializeComponent();

            PickAFileButton.Click += new RoutedEventHandler(PickAFileButton_Click);
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        private async void PickAFileButton_Click(object sender, RoutedEventArgs e)
        {
            FileOpenPicker openPicker = new FileOpenPicker();
            //设置呈现视图模式为缩略图
            openPicker.ViewMode = PickerViewMode.Thumbnail;
            //设置文件选择器打开时的起始位置,这里设置为图片库
            openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
            //添加文件过滤器
            openPicker.FileTypeFilter.Add(".jpg");
            openPicker.FileTypeFilter.Add(".jpeg");
            openPicker.FileTypeFilter.Add(".png");
            //异步调用PickSingleFileAsync
            StorageFile file = await openPicker.PickSingleFileAsync();
            if (file != null)
            {
                OutputTextBlock.Text = "Picked photo: " + file.Name;
            }
            else
            {
                OutputTextBlock.Text = "Operation cancelled.";
            }

        }
    }

 

效果图如下:

7)让用户选择多个文件

  使用的FileOpenPicker的PickMultipleFilesAsync方法来调用一个文件选择器窗口,
  让用户选择多个文件。

  修改我们的PickMultipleFiles.xaml

  代码如下:

View Code
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid x:Name="Input" Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <TextBlock Grid.Row="0" TextWrapping="Wrap" Style="{StaticResource SubheaderTextStyle}" HorizontalAlignment="Left" >
                Prompt the user to pick one or more files.
            </TextBlock>
            <Button Grid.Row="1" x:Name="PickFilesButton" Content="Pick files" Margin="0,10,10,0"/>
        </Grid>

        <Grid x:Name="Output" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">
            <TextBlock x:Name="OutputTextBlock" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap" />
        </Grid>
    </Grid>

  后台代码:

View Code
    public sealed partial class PickMultipleFiles : Page
    {
        public PickMultipleFiles()
        {
            this.InitializeComponent();
            PickFilesButton.Click += new RoutedEventHandler(PickFilesButton_Click);
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        private async void PickFilesButton_Click(object sender, RoutedEventArgs e)
        {
                FileOpenPicker openPicker = new FileOpenPicker();
                //设置呈现视图模式为列表
                openPicker.ViewMode = PickerViewMode.List;
                //设置文件选择器打开时的起始位置,这里设置为文档库
                openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
                //不过滤任何类型
                openPicker.FileTypeFilter.Add("*");
                //调用PickMultipleFilesAsync获得选择文件列表
                IReadOnlyList<StorageFile> files = await openPicker.PickMultipleFilesAsync();
                if (files.Count > 0)
                {
                    StringBuilder output = new StringBuilder("Picked files:\n");
                    foreach (StorageFile file in files)
                    {
                        output.Append(file.Name + "\n");
                    }
                    OutputTextBlock.Text = output.ToString();
                }
                else
                {
                    OutputTextBlock.Text = "Operation cancelled.";
                }
            }        
    }

 

效果图:

8)让用户选择一个文件夹

使用的FolderPicker的PickSingleFolderAsync方法来调用一个文件选择器窗口,
让用户选择一个文件夹。

修改我们的PickAFolder.xaml的xmal代码:

View Code
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid x:Name="Input" Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <TextBlock Grid.Row="0" TextWrapping="Wrap" Style="{StaticResource SubheaderTextStyle}" HorizontalAlignment="Left" >
                Prompt the user to pick a folder so its contents can be accessed later.
            </TextBlock>
            <Button Grid.Row="1" x:Name="PickFolderButton" Content="Pick folder" Margin="0,10,10,0"/>
        </Grid>

        <Grid x:Name="Output" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">
            <TextBlock x:Name="OutputTextBlock" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap" />
        </Grid>
    </Grid>

 

修改后台代码:

View Code
    public sealed partial class PickAFolder : Page
    {
        public PickAFolder()
        {
            this.InitializeComponent();
            PickFolderButton.Click += new RoutedEventHandler(PickFolderButton_Click);
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        private async void PickFolderButton_Click(object sender, RoutedEventArgs e)
        {
            FolderPicker folderPicker = new FolderPicker();
            folderPicker.SuggestedStartLocation = PickerLocationId.Desktop;
            folderPicker.FileTypeFilter.Add(".jpg");
            //调用PickSingleFolderAsync选择文件夹
            StorageFolder folder = await folderPicker.PickSingleFolderAsync();
            if (folder != null)
            {
                // 提供对列表的访问,使用该列表,应用程序可以跟踪最近访问的文件或位置和将来要存储的文件或位置
                StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolderToken", folder);
                OutputTextBlock.Text = "Picked folder: " + folder.Name;
            }
            else
            {
                OutputTextBlock.Text = "Operation cancelled.";
            }

        }
    }

 

效果图:

9)让用户保存文件和指定的名称,文件类型和/或保存位置

使用的FileSavePicker的PickSaveFileAsync方法来调用一个文件选择器窗口,
让用户保存文件。

修改我们的SaveAFile.xaml的代码:

View Code
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid x:Name="Input" Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>

            <TextBlock Grid.Row="0" TextWrapping="Wrap" Style="{StaticResource SubheaderTextStyle}" HorizontalAlignment="Left" >
                Prompt the user to save a file.
            </TextBlock>
            <Button Grid.Row="1" x:Name="SaveFileButton" Content="Save file" Margin="0,10,10,0"/>
        </Grid>

        <Grid x:Name="Output" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">
            <TextBlock x:Name="OutputTextBlock" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap" />
        </Grid>
    </Grid>

 

修改后台代码:

View Code
public sealed partial class SaveAFile : Page
    {
        public SaveAFile()
        {
            this.InitializeComponent();
            SaveFileButton.Click += new RoutedEventHandler(SaveFileButton_Click);
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        private async void SaveFileButton_Click(object sender, RoutedEventArgs e)
        {
            FileSavePicker savePicker = new FileSavePicker();
            savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
            // 指定要保存的类型
            savePicker.FileTypeChoices.Add("Plain Text", new List<string>() { ".txt" });
            // 默认的文件名
            savePicker.SuggestedFileName = "Refactor's blog";
            //调用保存文件方法
            StorageFile file = await savePicker.PickSaveFileAsync();
            if (file != null)
            {
                // 阻止更新,直到我们完成更新文件,我们完成更新后调用CompleteUpdatesAsync方法
                CachedFileManager.DeferUpdates(file);
                // 写文件
                await FileIO.WriteTextAsync(file, file.Name);
                // 让系统知道我们正在完成更新文件,以便其他程序可以更新该文件
                FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);
                if (status == FileUpdateStatus.Complete)
                {
                    OutputTextBlock.Text = "File " + file.Name + " was saved.";
                }
                else
                {
                    OutputTextBlock.Text = "File " + file.Name + " couldn't be saved.";
                }
            }
            else
            {
                OutputTextBlock.Text = "Operation cancelled.";
            }
        }

    }

 

效果图就不发了!你懂的,图太多了....

 

未完待续,敬请期待...

转载请注明出处:http://www.cnblogs.com/refactor/

posted on 2012-06-12 10:41  refactor  阅读(1864)  评论(2编辑  收藏  举报

导航