如何从UWP中的文件夹加载图像后立即将图像加载到页面

时间:2016-12-17 09:25:00

标签: c# xaml uwp

我使用AdaptiveGridView将文件夹中的图像列表加载到页面上。我的问题是如何在图像准备就绪后立即加载图像,而不必等待处理整个图像列表。 这是我的代码: C#

"Permission denied (publickey)."

XAML:

 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;

        }

我厌倦了移动for循环中的<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> ,但这减慢了过程,我不认为这是完成我在这里尝试做的最好的方法。还有其他建议吗? 谢谢

1 个答案:

答案 0 :(得分:1)

您应该使用ObservableCollection代替List。然后,您可以在添加图像之前将集合分配给ItemsSource属性。 ObservableCollection通知用户界面有关更改,例如关于添加的元素。

除此之外,您还应该使用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<ImageItem>();
    AdaptiveGV.ItemsSource = imageCollection;

    for ...
    {
        ...
        await bitmapimage.SetSourceAsync(stream); 

        ...
        imageCollection.Add(new ImageItem()
        {
            Image = bitmapimage,
            ImageText = filesList[i].Name
        });
    }
}

另请注意,我已将(令人困惑的)名称ImagesImageURL替换为 ImageItemImage。您必须将DataTemplate中的Image.Source绑定更改为:

<Image Source="{Binding Image}"

下一步可能是创建一个视图模型,将ObservableCollection<ImageItem>保存为(只读)属性:

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构造函数中将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属性,如下所示:

<UWPToolkit:AdaptiveGridView ...
    ItemsSource="{Binding ImageCollection}"
    ItemTemplate="{StaticResource PhotosList}" />