如何从UWP中的文件夹加载图像后立即将图像加载到页面
我正在使用AdaptiveGridView将文件夹中的图像列表加载到页面上。 我的问题是如何在图像准备好后立即加载图像,而不必等待处理整个图像列表。 这是我的代码:C#
public class Images { public ImageSource ImageURL { get; set; } public string ImageText { get; set; } } private List ImageCollection; private async void Button_Click(object sender, RoutedEventArgs e) { ImageCollection = new List(); // pick a folder var folderPicker = new Windows.Storage.Pickers.FolderPicker(); folderPicker.FileTypeFilter.Add(".jpg"); var folder = await folderPicker.PickSingleFolderAsync(); var filesList = await folder.CreateFileQueryWithOptions(new QueryOptions(CommonFileQuery.DefaultQuery, new string[] { ".jpg", ".png", ".jpeg" })).GetFilesAsync(); for (int i = 0; i < filesList.Count; i++) { StorageFile imagefile = filesList[i]; BitmapImage bitmapimage = new BitmapImage(); using (IRandomAccessStream stream = await imagefile.OpenAsync(FileAccessMode.Read)) { bitmapimage.SetSource(stream); } ImageCollection.Add(new Images() { ImageURL = bitmapimage, ImageText = filesList[i].Name }); countPhotos.Text = i.ToString() + "out of" + filesList.Count.ToString(); } AdaptiveGV.ItemsSource = ImageCollection; }
XAML:
我厌倦了移动AdaptiveGV.ItemsSource = ImageCollection;
在for循环中,但这减慢了过程,我不认为这是完成我在这里尝试做的最好的方法。 还有其他建议吗? 谢谢
您应该使用ObservableCollection
而不是List
。 然后,您可以在添加图像之前将集合分配给ItemsSource
属性。 ObservableCollection
通知UI有关更改,例如有关添加的元素的更改。
除此之外,您还应该使用async BitmapImage.SetSourceAsync()
方法。
public class ImageItem { public ImageSource Image { get; set; } public string ImageText { get; set; } } private async void Button_Click(object sender, RoutedEventArgs e) { var imageCollection = new ObservableCollection(); AdaptiveGV.ItemsSource = imageCollection; for ... { ... await bitmapimage.SetSourceAsync(stream); ... imageCollection.Add(new ImageItem() { Image = bitmapimage, ImageText = filesList[i].Name }); } }
另请注意,我已经用ImageItem
和Image
替换了(令人困惑的)名称Images
和ImageURL
。 您必须将DataTemplate中的Image.Source
绑定更改为:
下一步可能是创建一个视图模型,将ObservableCollection
为(只读)属性:
public class ViewModel { public ObservableCollection ImageCollection { get; } = new ObservableCollection (); public async Task LoadImages(StorageFolder folder) { var queryOptions = new QueryOptions( CommonFileQuery.DefaultQuery, new string[] { ".jpg", ".png", ".jpeg" }); var files = await folder.CreateFileQueryWithOptions(queryOptions).GetFilesAsync(); foreach (var file in files) { using (var stream = await file.OpenReadAsync()) { BitmapImage image = new BitmapImage(); await image.SetSourceAsync(stream); ImageCollection.Add(new ImageItem { Image = image, ImageText = file.Name }); } } } }
您可以在Page构造函数中将Page的DataContext
分配给视图模型的实例,并在Button Click上调用LoadImages()
方法:
public MainPage() { InitializeComponent(); DataContext = new ViewModel(); } private async void Button_Click(object sender, RoutedEventArgs e) { var folderPicker = new Windows.Storage.Pickers.FolderPicker(); folderPicker.FileTypeFilter.Add(".jpg"); var folder = await folderPicker.PickSingleFolderAsync(); if (folder != null) { await ((ViewModel)DataContext).LoadImages(folder); } }
在XAML中,您可以将ItemsSource属性绑定到ImageCollection属性,如下所示: