如何在从 UWP 中的文件夹加载图像后立即将图像加载到页面 [英] How to load images to a page as soon as they are loaded from a folder in UWP

查看:21
本文介绍了如何在从 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
        });
    }
}

另请注意,我已将(令人困惑的)名称 ImagesImageURL 替换为ImageItemImage.您必须将 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆