1

I have a gridview that displays 435 images on a local package. I tried using Incremental Loading.

XAML:

<GridView  
                            x:Name="komikGridView" Loaded="komikGridView_Loaded">
                                <GridView.Resources>
                                    <DataTemplate x:Key="DataTemplatekomikGridView">
                                        <Grid
                                        x:Name="komikGrid1">
                                            <Image
                                            x:Name="cover
                                            Width="160"
                                            Height="235"
                                            Source="{Binding Image}" />
                                        </Grid>
                                    </DataTemplate>
                                </GridView.Resources>
                                <GridView.ItemTemplate>
                                    <StaticResource ResourceKey="DataTemplatekomikGridView"/>
                                </GridView.ItemTemplate>
                            </GridView>

ItemsToShow Class:

public class ItemsToShow : ObservableCollection<string>, ISupportIncrementalLoading
    {
        public int lastItem = 1;

        public bool HasMoreItems
        {
            get
            {
                if (lastItem == 1000)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }

        public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
        {
            ProgressRing progressRing = ((Window.Current.Content as Frame).Content as LibraryPage).loading;
            CoreDispatcher coreDispatcher = Window.Current.Dispatcher;
            return Task.Run<LoadMoreItemsResult>(async () =>
            {
                await coreDispatcher.RunAsync(CoreDispatcherPriority.Normal,
                    () =>
                    {
                        progressRing.IsActive = true;
                        progressRing.Visibility = Visibility.Visible;
                    });

                //List<string> items = new List<string>();
                List<Book> items = new List<Book>();
                StorageFolder installedLocation = ApplicationData.Current.LocalFolder;
                StorageFolder _pdffolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
                _pdffolder = await _pdffolder.GetFolderAsync("files");
                _pdffolder = await _pdffolder.GetFolderAsync("pdf");
                _pdffolder = await _pdffolder.GetFolderAsync("komik");
                IReadOnlyList<StorageFile> _pdffiles = await _pdffolder.GetFilesAsync(); //which returns List<StorageFile>
                                                                                         //Debug.WriteLine("pdf: " + _pdffolder.Path);
                StorageFolder library = await installedLocation.CreateFolderAsync("library", CreationCollisionOption.OpenIfExists);
                StorageFolder komik = await library.CreateFolderAsync("komik", CreationCollisionOption.OpenIfExists);
                IReadOnlyList<StorageFile> files = await komik.GetFilesAsync();
                IEnumerable<Temp> sortingFiles = files.Select(x => new Temp { File = x }).ToList();
                foreach (var item in sortingFiles)
                {
                    //item.LastModified = (await item.File.GetBasicPropertiesAsync()).DateModified.DateTime;
                    item.Name = item.File.Name;
                }
                IEnumerable<StorageFile> sortedfiles = sortingFiles.OrderByDescending(x => x.LastModified).Select(x => x.File).ToList();
                StorageFolder _thumbfolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
                _thumbfolder = await _thumbfolder.GetFolderAsync("files");
                _thumbfolder = await _thumbfolder.GetFolderAsync("cover");
                _thumbfolder = await _thumbfolder.GetFolderAsync("komik");
                IReadOnlyList<StorageFile> _coverfiles = await _thumbfolder.GetFilesAsync(); //which returns List<StorageFile>
                StorageFolder thumbfolder = await installedLocation.CreateFolderAsync("thumb", CreationCollisionOption.OpenIfExists);
                StorageFolder komikthumb = await thumbfolder.CreateFolderAsync("komik", CreationCollisionOption.OpenIfExists);
                IReadOnlyList<StorageFile> thumbfiles = await komikthumb.GetFilesAsync();
                string filePath = "";
                foreach (StorageFile file in sortedfiles)
                {
                    Book book = new Book();
                    //FileItem book = new FileItem();
                    book.Name = file.DisplayName.ToString();
                    Debug.WriteLine("judul: " + book.Name);
                    StorageFile thumbFile = await komikthumb.GetFileAsync(file.Name.ToString() + ".png");
                    string path = komikthumb.Path;
                    filePath = Path.Combine(path, file.Name.ToString() + ".png");
                    BitmapImage bi = new BitmapImage();
                    bi.SetSource(await thumbFile.OpenAsync(FileAccessMode.Read));
                    book.Image = bi;
                    for (int i = 0; i < count; i++)
                    {
                        var p = new Book { Name = book.Name, Image = book.Image };
                        items.Add(p);
                        lastItem++;
                        if (lastItem == items.Count)
                        {
                            break;
                        }
                    }
                    Debug.WriteLine("jumlah: " + items.Count);
                }
                await coreDispatcher.RunAsync(CoreDispatcherPriority.Normal,
                    () =>
                    {
                        foreach (Book item in items)
                        {
                            //this.Add(item);
                            string _b64 = Convert.ToBase64String(File.ReadAllBytes(item.Path));
                            this.Add(_b64);
                        }
                        progressRing.Visibility = Visibility.Collapsed;
                        progressRing.IsActive = false;
                    });
                return new LoadMoreItemsResult() { Count = count };
            }).AsAsyncOperation<LoadMoreItemsResult>();
        }

        public class Temp
        {
            public StorageFile File { get; set; }
            public DateTime LastModified { get; set; }
            public string Name { get; set; }
        }
    }

Code:

private void komikGridView_Loaded(object sender, RoutedEventArgs e)
    {
        komikGridView.ItemsSource = new ItemsToShow();
    }

But I'm having a problem, i.e. the image doesn't display successfully on the gridview. How to handle it? And how to display 16 images first and when scrolled will display the next 16 images and so on?

Rose
  • 613
  • 4
  • 22
  • The replication problem is that you just have 11 image files, and it load same image folder each time when you scroll down. – Nico Zhu Jul 07 '22 at 05:39
  • If only 25-90 files, the image is successfully displayed on the gridview. But when I try to use 150 files or more, the image failed to display in gridview and displays an error message, like this image: https://1drv.ms/u/s!Av6G8Zq_Px8WhDBOYPax6GQRYMlZ?e=gO6fgi – Rose Jul 07 '22 at 07:07
  • You need check if there meory overflow when load so much loal file. – Nico Zhu Jul 07 '22 at 07:15
  • You use BitmapImage as book's property, and set value with local image that may case memory overflow, please use string property to replace. – Nico Zhu Jul 07 '22 at 07:27
  • how to convert BitmapImage to string? – Rose Jul 07 '22 at 07:39
  • firstly eidt bitmapimage type as string for book class , then pass thumbFile.Path to book image property. – Nico Zhu Jul 07 '22 at 07:46
  • I don't why you load the same folder each time that will make your data soure has duplicate items, and if you want to make mutiple pages for gridview, this document is best [practice](https://learn.microsoft.com/en-us/windows/communitytoolkit/helpers/incrementalloadingcollection) – Nico Zhu Jul 07 '22 at 08:21
  • And [here](https://ruphg-my.sharepoint.com/:u:/g/personal/vzhumin_teng_ai/Ee5a4sM1lMZDqtmnilga560BluztujkaNNJojf2D_i1ypg?e=1HabA7) is updated version, please note, for simulating the data I read the sortedfiles repeatedly 40 times, you could remove those line – Nico Zhu Jul 07 '22 at 09:28
  • the gridview is empty – Rose Jul 08 '22 at 02:15
  • It could work in my side. – Nico Zhu Jul 08 '22 at 02:19

1 Answers1

0

Displaying images in gridview using incremental loading

I found you refer this case reply, but for this scenario, you need to replace ObservableCollection<string> with ObservableCollection<Book>, because you have bind Image control with Book Image property.

 <Image x:Name="cover"  Width="160"  Height="235" Source="{Binding Image}" />

And the secondly you need to call Add metod to add Book instance but not base64 string. because image control can't render base64 directly.

await coreDispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
    foreach (Book item in items)
    {
        this.Add(item);
    }    
});

When you finished above, you could set break point in this.Add(item); line to check if it has avaiable item.

Update

Please try to call LoadMoreItemsAsync manually like the following.

private async void KomikContent()
 {
     var items = new ItemsToShow();
     komikGridView.ItemsSource = items;
     await items.LoadMoreItemsAsync(10);
 }

update 1

public class Book
{

    public string Name { get; set; }
    public string Image { get; set; }
}


await coreDispatcher.RunAsync(CoreDispatcherPriority.Normal,
async () =>
  {

      book.Image = thumbFile.Path;
      Add(book);
  });

update 2

And if you want to make mutiple pages for gridview, this document is best practice, you can refer it to make your own BookSource class and initialize data in it.

private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    var booksource = new BookSource();
    collection = new IncrementalLoadingCollection<BookSource,Book>(booksource, 35);
    komikGridView.ItemsSource = collection;
   
}
Nico Zhu
  • 32,367
  • 2
  • 15
  • 36