原教程地址:http://msdn.microsoft.com/zh-cn/library/windows/apps/xaml/jj655411.aspx
完整项目源码下载:http://download.csdn.net/detail/wxg694175346/5174187
步骤 1:使用文件选取器获取图像文件
通过文件选取器,你的应用可以在用户的整个系统上访问文件和文件夹。当你调用文件选取器时,用户可以浏览其系统并选择文件(或文件夹)以访问和保存。在用户选取文件或文件夹之后,你的应用将这些选取作为StorageFile和StorageFolder对象进行接收。接着你的应用可以通过使用这些对象在选取的文件和文件夹上操作。
你需要做的第一件事就是处理GetPhotoButton_Click
事件以获取要显示的图片。
我们先从部分 3:导航、布局和视图中的代码开始。
添加文件选取器
- 在“解决方案资源管理器”中,双击 PhotoPage.xaml 打开它。
- 选择“获取照片”""Button。
- 在“属性”窗口中,单击“事件”按钮 ()。
- 在事件列表的顶部查找Click事件。在事件的文本框中,键入 "GetPhotoButton_Click" 作为处理Click事件的方法的名称。
- 按 Enter。事件处理程序方法在代码编辑器中创建和打开,因此你可以添加在事件出现时执行的代码。
- 将async关键字添加到事件处理程序的方法签名中。
- 将此代码添加到事件处理程序方法中。该方法会打开文件选取器,让用户从图片库中选择一张图片。 当他们选取某个文件时,该文件会设置为图像源和页面的数据上下文。
// File picker APIs don't work if the app is in a snapped state. // If the app is snapped, try to unsnap it first. Only show the picker if it unsnaps. if (Windows.UI.ViewManagement.ApplicationView.Value != Windows.UI.ViewManagement.ApplicationViewState.Snapped || Windows.UI.ViewManagement.ApplicationView.TryUnsnap() == true) { Windows.Storage.Pickers.FileOpenPicker openPicker = new Windows.Storage.Pickers.FileOpenPicker(); openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary; openPicker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail; // Filter to include a sample subset of file types. openPicker.FileTypeFilter.Clear(); openPicker.FileTypeFilter.Add(".bmp"); openPicker.FileTypeFilter.Add(".png"); openPicker.FileTypeFilter.Add(".jpeg"); openPicker.FileTypeFilter.Add(".jpg"); // Open the file picker. Windows.Storage.StorageFile file = await openPicker.PickSingleFileAsync(); // file is null if user cancels the file picker. if (file != null) { // Open a stream for the selected file. Windows.Storage.Streams.IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read); // Set the image source to the selected bitmap. Windows.UI.Xaml.Media.Imaging.BitmapImage bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage(); bitmapImage.SetSource(fileStream); displayImage.Source = bitmapImage; this.DataContext = file; // mruToken = Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList.Add(file); } }
- 按 F5 构建并运行应用。导航到照片页面,然后单击""“获取照片”按钮启动FileOpenPicker。随即会出现照片,但照片信息文本还未更新。将在下一步中修复该问题。
以下是选择图片的应用的外观。
让我们来仔细查看使用FileOpenPicker的代码。若要使用文件选取器,你需要执行 3 个基本步骤:确保文件选取器可以打开,创建并自定义文件选取器对象以及显示文件选取器以使用户可以选取一个项。
你无法在辅视图中打开文件选取器。因此,在调用文件选取器之前,必须首先确保应用未贴靠,如果贴靠,则必须调用TryUnsnap方法来取消贴靠。
if (Windows.UI.ViewManagement.ApplicationView.Value != Windows.UI.ViewManagement.ApplicationViewState.Snapped || Windows.UI.ViewManagement.ApplicationView.TryUnsnap() == true)
接下来,创建FileOpenPicker对象。
Windows.Storage.Pickers.FileOpenPicker openPicker = new Windows.Storage.Pickers.FileOpenPicker();
在文件选取器对象上设置与你的用户和你的应用相关的属性。有关帮助你确定如何自定义文件选取器的指南,请参阅文件选取器指南。
由于用户正在选取图片,因此会将SuggestedStartLocation设置为图片库,将ViewMode设置为Thumbnail。还会添加文件类型筛选器,以便选取器仅显示为图像文件指定的文件类型。
openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary; openPicker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail; // Filter to include a sample subset of file types. openPicker.FileTypeFilter.Clear(); openPicker.FileTypeFilter.Add(".bmp"); openPicker.FileTypeFilter.Add(".png"); openPicker.FileTypeFilter.Add(".jpeg"); openPicker.FileTypeFilter.Add(".jpg");
在你创建和自定义文件选取器后,调用FileOpenPicker.PickSingleFileAsync以显示该选取器并让用户选取一个文件。
注意若要让用户选取多个文件,请调用PickMultipleFilesAsync。
// Open the file picker. Windows.Storage.StorageFile file = await openPicker.PickSingleFileAsync();
用户选取文件时,PickSingleFileAsync返回表示已选取文件的StorageFile对象。处理图像流以创建BitmapImage并将BitmapImage设置为 UI 中Image控件的Source。还将文件设置为页面的DataContext,以便可以将 UI 元素绑定到其属性。
// file is null if user cancels the file picker. if (file != null) { // Open a stream for the selected file Windows.Storage.Streams.IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read); // Set the image source to the selected bitmap. Windows.UI.Xaml.Media.Imaging.BitmapImage bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage(); bitmapImage.SetSource(fileStream); displayImage.Source = bitmapImage; this.DataContext = file; }
步骤 2:将 UI 控件绑定到文件数据
此时,图像会显示在 UI 中,但图像文件属性不会显示在添加的文本块中。可以在代码中设置每个TextBlock的Text属性,就像设置Image.Source属性一样。
但对于显示数据,通常会使用“数据绑定”将数据源连接到 UI,方法是设置Binding.Source属性或在 UI 元素上设置DataContext。建立绑定后,如果数据源发生更改,绑定到该数据源的 UI 元素可以自动反映更改内容。
注意默认情况下,绑定为one-way,这表示数据源的更新会在 UI 中反映出来。你可以指定two-way绑定,以便用户在 UI 元素中所做的更改可以在数据源中反映出来。例如,如果用户编辑了TextBox中的值,则绑定引擎将自动更新基础数据源以反映该变化。
使用DataContext属性可设置整个 UI 元素的默认绑定,包括其所有子元素。将在FileOpenPicker中选择的StorageFile设置为照片页面的DataContext。请注意,在选取图像后,将使用此代码行设置DataContext。
此时,通过将标题TextBlock的Text属性绑定到所选文件的StorageFile.DisplayName属性来显示文件名。
由于不指定绑定的Source,因此数据绑定引擎会在DataContext上查找DisplayName属性。如果DataContext为null或没有DisplayName属性,则绑定会失败并且不会给出任何提示,且TextBlock中不会显示任何文本。
此时,将TextBlock控件绑定到StorageFile属性。
将控件绑定到数据
- 在“解决方案资源管理器”中,双击 PhotoPage.xaml 打开它。
- 为“获取照片”""按钮下的照片名称选择TextBlock。
- 在“属性”面板中,单击“属性”按钮 ()以显示“属性”视图。
- 在“属性”面板的“常用”下,单击Text属性的“属性标记”。此时将打开“属性”菜单。
注意“属性标记”是每个属性值右侧的小框符号。Text属性标记为黑色,表示该属性已设置为字符串值。
- 在“属性”菜单中,选择“创建数据绑定...”。随即将打开“创建数据绑定”对话框。
- 在“创建数据绑定”对话框中,选择“绑定类型”下拉列表中的“数据上下文”。
- 在此处显示的“路径”文本框中输入 "DisplayName"。
注意“创建数据绑定”对话框中的消息表明数据上下文尚未设置。这是可以的,因为在运行应用和获取图片时会在代码中设置数据上下文。
- 单击“确定”。
下面是添加绑定后TextBlock的可扩展应用程序标记语言 (XAML)。
<TextBlock Grid.Row="1" TextWrapping="Wrap" Text="{Binding DisplayName}" Style="{StaticResource PageSubheaderTextStyle}"/>
- 选择“文件名:”""后的TextBlockTextBlock。
- 重复步骤 3-5 为此TextBlock创建数据绑定。
- 在“路径”文本框中输入 "Name" 并单击“确定”。
- 选择“路径:”""后的TextBlockTextBlock。
- 重复步骤 3-5 为此TextBlock创建数据绑定。
- 在“路径”文本框中输入 "Path" 并单击“确定”。
- 选择“创建日期:”""后的TextBlockTextBlock。
- 重复步骤 3-5 为此TextBlock创建数据绑定。
- 在“路径”文本框中输入“DateCreated”""并单击“确定”。
下面是添加绑定后照片信息StackPanel的 XAML。
<StackPanel Margin="20,0,0,0"> <TextBlock Text="File name:" Style="{StaticResource CaptionTextStyle}"/> <TextBlock Text="{Binding Name}" Style="{StaticResource ItemTextStyle}" Margin="10,0,0,30"/> <TextBlock Text="Path:" Style="{StaticResource CaptionTextStyle}"/> <TextBlock Text="{Binding Path}" Style="{StaticResource ItemTextStyle}" Margin="10,0,0,30"/> <TextBlock Text="Date created:" Style="{StaticResource CaptionTextStyle}"/> <TextBlock Text="{Binding DateCreated}" Style="{StaticResource ItemTextStyle}" Margin="10,0,0,30"/> </StackPanel>
- 按 F5 构建并运行应用。导航到照片页。单击“获取照片”""按钮可启动FileOpenPicker。使用适当的绑定,当选取文件时不会显示文件属性。
以下是当选择图片和将文本块绑定到数据时应用的外观。
步骤 3:保存和加载状态
在此教程系列的部分 2:管理应用生命周期和状态中,你已了解到如何保存和还原应用状态。在将新页面添加到应用后,还需要保存和加载新页面的状态。有关照片页面,只需保存和还原当前显示的图像文件。
但是无法仅将路径保存到文件,然后使用该路径重新打开该文件。当用户选取具有FileOpenPicker的文件时,他们会隐式授予应用该文件的权限。如果你尝试以后仅使用该路径检索文件,则拒绝使用该权限。
相反,若要保留该文件的访问权限以便将来使用,则StorageApplicationPermissions类提供了 2 个列表,你可以在其中存储文件及其权限,当用户使用文件选取器打开该文件时会授予这些权限。
- MostRecentlyUsedList- 用于存储最后访问的 25 个文件。
- FutureAccessList- 用于常规存储,最多 1000 个文件,以便将来访问。
当用户选取文件后,会将其添加到MostRecentlyUsedList。我们将文件添加到此列表后,MostRecentlyUsedList会返回你用于以后检索文件的令牌。将此令牌保存在pageState
字典中,并使用该令牌在还原页面状态时检索当前图像文件。
保存状态
- 在“解决方案资源管理器”中,双击 PhotoPage.xaml.cs/vb 打开它。
- 在
PhotoPage
类的顶部,添加此代码。该代码会声明一个变量来保存MostRecentlyUsedList返回的令牌。以下是该代码及其周围代码。
- 在
GetPhotoButton_Click
事件处理程序中,添加此代码。该代码将选取的文件添加到MostRecentlyUsedList并获取令牌。// Add picked file to MostRecentlyUsedList. mruToken = Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList.Add(file);
以下是该代码及其周围代码。
// file is null if user cancels the file picker. if (file != null) { // Open a stream for the selected file. Windows.Storage.Streams.IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read); // Set the image source to the selected bitmap. Windows.UI.Xaml.Media.Imaging.BitmapImage bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage(); bitmapImage.SetSource(fileStream); displayImage.Source = bitmapImage; this.DataContext = file; // Add picked file to MostRecentlyUsedList. mruToken = Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList.Add(file); }
- 在
SaveState
方法中,添加此代码。该代码会检查令牌是否存在,如果存在,则将其保存在pageState
字典中。以下是
SaveState
方法的完整代码。
加载状态
- 在 PhotoPage.xaml.cs/vb 中,向
LoadState
方法签名添加async关键字。 - 在
LoadState
方法中添加此代码。此时,从
pageState
字典中获取令牌。使用该令牌从MostRecentlyUsedList中检索文件并还原 UI 状态。if (pageState != null && pageState.ContainsKey("mruToken")) { object value = null; if (pageState.TryGetValue("mruToken", out value)) { if (value != null) { mruToken = value.ToString(); // Open the file via the token that you stored when adding this file into the MRU list. Windows.Storage.StorageFile file = await Windows.Storage.AccessCache.StorageApplicationPermissions.MostRecentlyUsedList.GetFileAsync(mruToken); if (file != null) { // Open a stream for the selected file. Windows.Storage.Streams.IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read); // Set the image source to a bitmap. Windows.UI.Xaml.Media.Imaging.BitmapImage bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage(); bitmapImage.SetSource(fileStream); displayImage.Source = bitmapImage; // Set the data context for the page. this.DataContext = file; } } } }
- 按 F5 构建并运行应用。导航至照片页面,然后单击“获取照片”""按钮以启动FileOpenPicker并选取文件。当应用挂起、终止以及还原时,会立即重新加载图像。
注意查看部分 2:管理应用生命周期和状态获取有关如何挂起、终止以及还原应用的说明。