如何在从 UWP 中的文件夹加载图像后立即将图像加载到页面 [英] How to load images to a page as soon as they are loaded from a folder in UWP
问题描述
我正在使用 AdaptiveGridView 将文件夹中的图像列表加载到页面上.我的问题是如何在图像准备好后立即加载图像,而不必等待处理整个图像列表.这是我的代码:C#
I'm using the AdaptiveGridView to load a list of images from a folder onto the page. my question is how can i load an image as soon as it's become ready and not have to wait for the entire list of images to be processed. Here's my code: C#
public class Images
{
public ImageSource ImageURL { get; set; }
public string ImageText { get; set; }
}
private List<Images> ImageCollection;
private async void Button_Click(object sender, RoutedEventArgs e)
{
ImageCollection = new List<Images>();
// 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:
<Page.Resources>
<DataTemplate x:Key="PhotosList">
<Grid>
<Image Source="{Binding ImageURL}"
Stretch="UniformToFill"
HorizontalAlignment="Center"
VerticalAlignment="Center">
</Image>
</Grid>
</DataTemplate>
</Page.Resources>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button HorizontalAlignment="Left" VerticalAlignment="Top" Content="click me" Click="Button_Click">
</Button>
<TextBlock Name="countPhotos">
</TextBlock>
<ScrollViewer>
<UWPToolkit:AdaptiveGridView x:Name="AdaptiveGV"
ItemHeight="300" DesiredWidth="500"
ItemTemplate="{StaticResource PhotosList}">
</UWPToolkit:AdaptiveGridView>
</ScrollViewer>
</StackPanel>
我厌倦了在 for 循环内移动 AdaptiveGV.ItemsSource = ImageCollection;
但这减慢了进程,我认为这不是完成我在这里尝试做的事情的最佳方式.还有其他建议吗?谢谢
I tired moving the AdaptiveGV.ItemsSource = ImageCollection;
inside of the for loop but that slowed down the process and I dont think its the best way to accomplish what i'm trying to do here. any other suggestions?
Thanks
推荐答案
您应该使用 ObservableCollection
而不是 List
.然后,您可以在添加图像之前将集合分配给 ItemsSource
属性.ObservableCollection
通知 UI 有关更改,例如关于添加的元素.
You should use an ObservableCollection
instead of a List
. You could then assign the collection to the ItemsSource
property before adding the images. The ObservableCollection
notifies the UI about changes, e.g. about added elements.
除此之外,您还应该使用 async BitmapImage.SetSourceAsync()
方法.
Besides that, you should also use the async BitmapImage.SetSourceAsync()
method.
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<ImageItem>();
AdaptiveGV.ItemsSource = imageCollection;
for ...
{
...
await bitmapimage.SetSourceAsync(stream);
...
imageCollection.Add(new ImageItem()
{
Image = bitmapimage,
ImageText = filesList[i].Name
});
}
}
另请注意,我已将(令人困惑的)名称 Images
和 ImageURL
替换为ImageItem
和 Image
.您必须将 DataTemplate 中的 Image.Source
绑定更改为:
Note also that I've replaced the (confusing) names Images
and ImageURL
by
ImageItem
and Image
. You would have to change the Image.Source
Binding in the DataTemplate to this:
<Image Source="{Binding Image}"
<小时>
下一步可能是创建一个视图模型,将 ObservableCollection
作为(只读)属性保存:
The next step could be to create a view model that holds the ObservableCollection<ImageItem>
as a (read-only) property:
public class ViewModel
{
public ObservableCollection<ImageItem> ImageCollection { get; }
= new ObservableCollection<ImageItem>();
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 的 DataContext
分配给 Page 构造函数中的视图模型实例,并在 Button Click 上调用 LoadImages()
方法:
You would assign the Page's DataContext
to an instance of the view model in the Page constructor and call the LoadImages()
method on Button Click:
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 属性:
In XAML, you would bind the ItemsSource property to the ImageCollection property like this:
<UWPToolkit:AdaptiveGridView ...
ItemsSource="{Binding ImageCollection}"
ItemTemplate="{StaticResource PhotosList}" />
这篇关于如何在从 UWP 中的文件夹加载图像后立即将图像加载到页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!