在 Windows 10 App 中将图片从图片库填充到 ListView
Posted
技术标签:
【中文标题】在 Windows 10 App 中将图片从图片库填充到 ListView【英文标题】:populate images from picture library to ListView in Windows 10 App 【发布时间】:2017-04-30 08:17:36 【问题描述】:我正在尝试在 Windows 应用程序中将默认图片库中的所有图像显示到 ListView,但我只能显示图像的名称而不是文件夹中的所有图像,这是我的代码。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Media.Imaging;
using Windows.Storage.Streams;
using Windows.Storage;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace ListView
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
public MainPage()
this.InitializeComponent();
showall();
public async void showall()
IReadOnlyList<StorageFile> file = await KnownFolders.PicturesLibrary.GetFilesAsync();
foreach (StorageFile file1 in file)
list.Items.Add(file1.Name);
这里是 xaml 代码...
<Page
x:Class="ListView.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ListView"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="ThemeResource ApplicationPageBackgroundThemeBrush">
<StackPanel>
<StackPanel HorizontalAlignment="Left" Width="350" Height="350">
<ListView Width="300" Height="300" Name="list" SelectionChanged="list_SelectionChanged">
<Image Width="200" Height="200" Name="img"></Image>
</ListView>
</StackPanel>
<StackPanel VerticalAlignment="Top">
<Image Width="300" Height="300" Name="img1" />
<TextBlock Width="300" Height="30" Name="txt1" />
</StackPanel>
</StackPanel>
</Grid>
【问题讨论】:
这里是listView设计的图片链接:prntscr.com/djhu3f 那么问题出在哪里?用于绑定此的 xaml 在哪里? @AVKNaidu 编辑检查以上 【参考方案1】:没有从 StorageFile 名称到图像的自动转换。
您需要两件事,首先是在 ListView 中带有 Image 控件的 DataTemplate:
<ListView x:Name="list">
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="Binding"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
第二,从StorageFiles创建的BitmapImages,添加到Items集合而不是文件名:
public MainPage()
InitializeComponent();
Loaded += OnLoaded;
private async void OnLoaded(object sender, RoutedEventArgs e)
list.Items.Clear();
var files = await KnownFolders.PicturesLibrary.GetFilesAsync();
foreach (var file in files)
var bitmap = new BitmapImage();
using (var stream = await file.OpenReadAsync())
await bitmap.SetSourceAsync(stream);
list.Items.Add(bitmap);
还要注意,加载是在Loaded
事件处理程序中完成的,而不是直接调用异步方法而不等待它。事件处理程序是唯一可以安全地成为 async void
且无需等待的方法。
【讨论】:
每张图片加载2次,如何设置这些图片的像素? Loaded 处理程序可能被调用了两次(不知道为什么)。我已经对其进行了更改,以便它最初清除列表。除此之外,如何设置像素数据是一个完全不同的问题。请不要在 cmets 中问后续问题。而是在 *** 上提出一个新问题。【参考方案2】:虽然 Clemens 的方法适合您,但我想向您展示一种不同的方法。使用 ViewModel。
这是一个 PicturesViewModel:
public class PicturesViewModel
public ObservableCollection<ImageSource> MyImages get;
= new ObservableCollection<ImageSource>();
public async Task GetImages()
var files = await KnownFolders.PicturesLibrary.GetFilesAsync();
foreach (var file in files)
using (var stream = await file.OpenReadAsync())
BitmapImage image = new BitmapImage();
await image.SetSourceAsync(stream);
MyImages.Add(image);
通常如果它是一个同步活动,你可以在构造函数中编写你的逻辑。由于这是异步的,我在我的视图模型中使用另一种方法来加载 List
的 BitmapImage
s
现在在您的MainPage_Loaded
(MainPage 的Loaded
事件的处理方法,如另一个答案所示)中,您需要这样做:
private async void MainPage_Loaded(object sender, RoutedEventArgs e)
var viewModel = new PicturesViewModel();
DataContext = viewModel;
await viewModel.GetImages();
而您的 ListView 只是 Binding
<ListView ItemsSource="Binding MyImages">
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="Binding"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
【讨论】:
修复了 XAML 并更改了视图模型以使用广泛接受的属性名称命名约定。关于 DataContext 的代码注释也是错误的。 ListView从Page继承DataContext,所以设置list.DataContext
还是this.DataContext
都没有关系。后者更好,因为 Page 中的其他元素可以绑定到同一个视图模型。此外,从 GetImages() 方法返回视图模型实例没有意义。
在 Loaded 处理程序中实例化视图模型也不是严格要求的。您也可以在 MainPage 构造函数中执行此操作。重要的是在 Loaded 处理程序中调用异步 GetImages() 方法。
在我们进行改进的同时,我还将 MyImages 集合更改为只读,并将元素类型更改为 ImageSource,这是 BitmapImage 的一个基类,它提供了更大的灵活性您可以传递给集合的位图类型的数量,例如WriteableBitmap 而不是 BitmapImage。以上是关于在 Windows 10 App 中将图片从图片库填充到 ListView的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Scriptable App 中将 Base64 转换为图像