2015-07-21 106 views
1

我有大量的圖片需要加載到我的wpf應用程序中。我用BackgroundWorker嘗試了它,但它不能在顯示圖像的位置創建togglebutton。在wpf中加載很多圖片

有沒有更好的方法來加載大量的圖像?它們需要可選,因爲用戶可以選擇圖像。

這裏有一點到目前爲止我的代碼:

<WrapPanel Name="mFolderImages"> 
    <ToggleButton Width="150" Margin="5" Style="{StaticResource ImageList}"> 
     <ToggleButton.Content> 
       <Image Source="/Managment;component/images/example.png" /> 
     </ToggleButton.Content> 
    </ToggleButton> 
</WrapPanel> 

private void GetFolderImagesThreadFinished(object sender, RunWorkerCompletedEventArgs e) { 
     if (e.Result != null && e.Result is List<BitmapImage>) { 
      List<BitmapImage> images = (List<BitmapImage>)e.Result; 
      foreach (var image in images) { 
       Image img = new Image(); 
       img.Source = image; 
       img.Margin = new Thickness(5); 

       ToggleButton btn = new ToggleButton(); 
       btn.Content = img; 
       btn.Width = 150; 
       btn.Margin = new Thickness(5); 
       btn.IsEnabled = true; 
       btn.Click += ChangeSelectedImage; 
       btn.Style = this.FindResource("ImageList") as Style; 
       mFolderImages.Children.Add(btn); 
      } 
     } 
     mProgress.Visibility = Visibility.Collapsed; 
     mFolderImages.IsEnabled = true; 
    } 

    private void GetFolderImagesThread(object sender, DoWorkEventArgs e) { 
     string imagePath = Config.GetValue("ImagePath"); 
     if (!Directory.Exists(imagePath)) return; 

     string[] files = Directory.GetFiles(imagePath); 
     int progress = 0; 
     List<BitmapImage> images = new List<BitmapImage>(); 

     foreach(var file in files) { 
      if (file.EndsWith(".jpg") || file.EndsWith(".png")) { 
       try { 
        BitmapImage bmp = new BitmapImage(); 
        bmp.BeginInit(); 
        bmp.UriSource = new Uri(file, UriKind.Absolute); 
        bmp.EndInit(); 
        bmp.Freeze(); 
        images.Add(bmp); 
       } catch (Exception ex) { 
        Console.Write(ex.Message); 
       } 
      } 
      ++progress; 
      mThread.ReportProgress((int)((progress/(float)files.Length) * 100)); 
     } 
     e.Result = images; 
    } 
+0

[與WPF線程加載圖像]的可能重複(http://stackoverflow.com/questions/1738978/loading-image-in-thread-with-wpf) –

+0

很難說沒有看過任何的代碼。 – Clemens

+0

@Clemens增加了一些代碼 – Calypoter

回答

3

所有圖像創建一個列表框,創建圖像的obersvable集合。我不會使用圖像,但會創建圖像分辨率較低的縮略圖。
圖像的每個viewModel將使用視圖模型的數據模板顯示,該模型將顯示縮略圖。
也有一個快速瀏覽一下這裏的圖片 Loading Images asynchronous in C#

<ListBox ItemsSource="{Binding ImagesCollection}" 
    SelectedIndex="0"> 
    <ListBox.ItemTemplate> 
    <DataTemplate> 
     <Image Source="{Binding}"/> <!--bind to the field of the tumbnail using a converter if needed 
    </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 
0

確定的異步加載,我知道了。

在ItemsPanel中使用帶有Wrappanel的xaml中的Listbox以及ItemTemplate中的圖像。

然後在代碼中,我使用BackgroundWorker加載並調整圖像大小,並使用reportProgress將其添加到集合中。

<ListBox ItemsSource="{Binding Path=ImagesCollection, IsAsync=True}" SelectedIndex="0" ScrollViewer.HorizontalScrollBarVisibility="Disabled"> 
    <ListBox.ItemsPanel> 
     <ItemsPanelTemplate> 
      <WrapPanel IsItemsHost="True" /> 
     </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <Image Width="150" Height="150" Source="{Binding}" /> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

private void LoadImageProgress(object sender, ProgressChangedEventArgs e) { 
     if (e.UserState != null && e.UserState is BitmapImage) { 
      ImagesCollection.Add((BitmapImage)e.UserState); 
     } 
    } 

    private void LoadImageThread(object sender, DoWorkEventArgs e) { 
     string imagePath = Config.GetValue("ImagePath"); 
     if (!Directory.Exists(imagePath)) return; 

     string[] files = Directory.GetFiles(imagePath); 
     foreach (var file in files) { 
      if (file.EndsWith(".jpg") || file.EndsWith(".png")) { 
       var img = new Bitmap(file); 
       float scale = Math.Min(150/(float)img.Width, 150/(float)img.Height); 

       var bmp = new Bitmap(150, 150); 
       var graph = Graphics.FromImage(bmp); 

       var scaleWidth = (int)(img.Width * scale); 
       var scaleHeight = (int)(img.Height * scale); 

       graph.DrawImage(img, new System.Drawing.Rectangle((150 - scaleWidth)/2, (150 - scaleHeight)/2, scaleWidth, scaleHeight)); 

       BitmapImage retImg = new BitmapImage(); 
       using (MemoryStream mem = new MemoryStream()) { 
        bmp.Save(mem, System.Drawing.Imaging.ImageFormat.Bmp); 
        mem.Position = 0; 
        retImg.BeginInit(); 
        retImg.StreamSource = mem; 
        retImg.CacheOption = BitmapCacheOption.OnLoad; 
        retImg.EndInit(); 
        retImg.Freeze(); 
       } 
       mThread.ReportProgress(0, retImg); 

       if (mThread.CancellationPending) return; 
       //Thread.Sleep(1000); 
      } 
     } 
    }