2010-06-30 82 views
6

我有大約45張體積很大的圖像(大約680x1000)需要加載到一個簡單的用戶控件(帶填充,圖像,文本塊和2邊矩形的圓形邊框)中,然後顯示在一個包裝中。由於圖像在程序加載時全部可見,因此虛擬化對此不會有幫助。WPF:如何快速將大量大圖片加載到wrappanel中?

我知道里面的BitmapImage初始化我可以設置decodepixel寬度,這有一點幫助,但是id喜歡加載它們全部作爲全尺寸,因爲我想能夠調整圖像的大小而不會丟失質量(這部分大部分工作很快)。我知道一種可能性是將解碼寬度設置爲我設置的最大可視大小可以幫助的某個數字。

我嘗試了在How do I load images in the background?(第一個答案)中找到的多線程方法,但它導致程序花費很長的時間來加載!

任何想法?

電流負載代碼:

BitmapImage bmp = new BitmapImage(); 
bmp.BeginInit(); 
//bmp.DecodePixelWidth = 400; 
bmp.UriSource = new Uri(file.FullName); 
bmp.EndInit(); 
bmp.Freeze(); 
images.Add(bmp); 

樣品XAML代碼:

 <Border x:Name="backBorder" Background="Black" Padding="2" Margin="3" CornerRadius="3,3,4,4" 
      BorderBrush="Black" BorderThickness="1" 
      MouseEnter="backBorder_MouseEnter" MouseLeave="backBorder_MouseLeave" MouseLeftButtonUp="backBorder_MouseLeftButtonUp" > 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition /> 
      <RowDefinition Height="16" /> 
     </Grid.RowDefinitions> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition /> 
      <ColumnDefinition Width="15" /> 
     </Grid.ColumnDefinitions> 
     <Image x:Name="imageBox" Stretch="Fill" Width="{Binding Path=ImageWidth, ElementName=me}" Height="{Binding Path=ImageHeight, ElementName=me}" /> 
     <Border x:Name="backRatingBorder" Grid.Column="1" Margin="3,0,0,0" BorderBrush="Blue" Background="White" BorderThickness="1"/> 
     <Border x:Name="frontRatingBorder" Grid.Column="1" Margin="3,0,0,0" BorderBrush="Blue" Background="LightBlue" BorderThickness="1" VerticalAlignment="Bottom" Height="50"/> 
     <TextBlock x:Name="textBlock" Grid.Row="1" Grid.ColumnSpan="2" TextAlignment="Center" Background="Transparent" Foreground="White" FontFamily="Segoe UI" FontWeight="SemiBold" FontSize="12" /> 
    </Grid> 
</Border> 

UPDATE:

嗯,我最終作出通過運行在一個單一的後臺工作負載圖像循環更加適應。每個圖像加載後,調用Dispacher.Invoke來創建換行項目。玩了一段時間後,我得到它顯示每個項目,因爲它是在以前的同一時間創建的。

回答

1

如果您對整體性能感到滿意,只需加載圖像,就可以嘗試this Multithreaded UI tutorial.我設法讓它很容易地工作,但如果您將所有圖像加載到循環中, t更新視覺效果,直到完成加載所有圖像。然而,UI在這段時間內是有響應的,因爲所有的加載都在一個單獨的線程上。

或者,如果您要將所有圖像加載到循環中,則可以嘗試improved version of Windows Forms DoEvents method(向下滾動至示例)。你可以在加載完每個圖像後調用它,它會讓UI有機會更新自己(處理用戶交互等)。這是我爲我的項目加載地圖圖塊時使用的方法,比第一個方法更簡單。

+1

我認爲我的主要問題是從磁盤到內存的實際加載的圖像。我不確定是否有什麼我可以在這裏修復的,是嗎?我將所有圖像加載到一個列表中,然後生成所有包含列表中對BitmapImages的引用的換行項目。我可以清除所有包裝兒童並重新創建它們,但裝載本身需要幾秒鐘的時間。我嘗試了一個Parallel.For循環來將圖像加載到列表中,但它導致它們加載速度較慢,可能是由於異步磁盤訪問。 – user380527 2010-07-01 04:04:18