Why program crashes by adding a lot of images to listview?

后端 未结 2 894
庸人自扰
庸人自扰 2021-01-17 08:44

This is my XAML:

         


        
2条回答
  •  旧巷少年郎
    2021-01-17 09:08

    You could have a view model that loads thumbnail image files asynchronously, and also limits their size by setting the DecodePixelWidth or DecodePixelHeight property.

    public class ImageData
    {
        public string Name { get; set; }
        public ImageSource ImageSource { get; set; }
    }
    
    public class ViewModel
    {
        public ObservableCollection Images { get; }
            = new ObservableCollection();
    
        public async Task LoadFolder(string folderName, string extension = "*.jpg")
        {
            Images.Clear();
    
            foreach (var path in Directory.EnumerateFiles(folderName, extension))
            {
                Images.Add(new ImageData
                {
                    Name = Path.GetFileName(path),
                    ImageSource = await LoadImage(path)
                });
            }
        }
    
        public Task LoadImage(string path)
        {
            return Task.Run(() =>
            {
                var bitmap = new BitmapImage();
    
                using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
                {
                    bitmap.BeginInit();
                    bitmap.DecodePixelHeight = 100;
                    bitmap.CacheOption = BitmapCacheOption.OnLoad;
                    bitmap.StreamSource = stream;
                    bitmap.EndInit();
                    bitmap.Freeze();
                }
    
                return bitmap;
            });
        }
    }
    

    You would bind to such a view model like this:

    
        
    
    ...
    
        
            
                
            
        
        
            
                
                    
                        
                        
                    
                    
                    
                
            
        
    
    

    And populate it e.g. in some async input event handler, like:

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        await ((ViewModel)DataContext).LoadFolder(...);
    }
    

提交回复
热议问题