Images in Background Workers in WPF Application

后端 未结 1 822
傲寒
傲寒 2020-12-22 08:24

I have the following code snippet that I use to create a List to add to a scrollviewer as a binding in a WPF application:

private void LoadThumbs(object send         


        
1条回答
  •  情深已故
    2020-12-22 09:13

    Do not create Image elements in code behind. Instead, use an ItemControl with an appropriate ItemTemplate:

    
        
            
                
                    
                
            
        
    
    

    Bind it to a view model like shown below, which is capable of asynchronously loading the image files. It is important that the BitmapImages are frozen to make them cross-thread accessible.

    public class ViewModel
    {
        public ObservableCollection Images { get; }
            = new ObservableCollection();
    
        public async Task LoadImagesAsync(IEnumerable filenames)
        {
            foreach (var filename in filenames)
            {
                Images.Add(await Task.Run(() => LoadImage(filename)));
            }
        }
    
        public ImageSource LoadImage(string filename)
        {
            var bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.CacheOption = BitmapCacheOption.OnLoad;
            bitmap.DecodePixelWidth = 200;
            bitmap.UriSource = new Uri(filename);
            bitmap.EndInit();
            bitmap.Freeze();
            return bitmap;
        }
    }
    

    which is initialized like this:

    private ViewModel viewModel = new ViewModel();
    
    public MainWindow()
    {
        InitializeComponent();
        DataContext = viewModel;
    }
    
    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        ...
        await viewModel.LoadImagesAsync(..., "*.jpg"));
    }
    

    An alternative view model method could load the BitmapImages directly from a FileStream instead of an Uri:

    public ImageSource LoadImage(string filename)
    {
        using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read))
        {
            var bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.DecodePixelWidth = 200;
            bitmap.CacheOption = BitmapCacheOption.OnLoad;
            bitmap.StreamSource = stream;
            bitmap.EndInit();
            bitmap.Freeze();
            return bitmap;
        }
    }
    

    0 讨论(0)
提交回复
热议问题