2011-09-06 23 views
2

我想使用一個ListView組件來顯示大約1,000個圖像縮略圖,我有一些性能問題。爲什麼帶有ImageList的ListView非常慢? (重新:1000 +縮略圖)

首先我創建一個包含我的1,000張圖像的ImageList。這閃電很快,需要一秒鐘。

但是,一旦我將ImageList分配給我的ListView,大約需要10多秒。

例子:

ImageList _imgList = GetMyImageList(); // takes under 1 second 
ListView _lstView = new ListView(); 
lstView.LargeImageList = _imgList; // takes 10+ seconds 

有什麼我可以做,以提高性能?我的ImageList包含已經調整爲縮略圖大小(197x256像素)的圖像,所以這不是問題...(並且創建我的ImageList最多隻需要1秒)。

+0

看到我的答案在下面,並嘗試在您的機器上的代碼,並讓我知道如果有加載時間的差異。 –

回答

0

列表視圖中的數據是否頻繁更改?你是否經常加載新的圖片列表?

我試過了你的場景,並且在更改列表視圖[View]模式以及滾動時,加載時間(因爲我生成的是隨機圖像),但刷新時間非常快。

以下是示例代碼。試試看,讓我知道它是如何工作的。

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Drawing; 
using System.Linq; 
using System.Windows.Forms; 

namespace WindowsFormsApplication10 
{ 
    public partial class FormListView: 
     System.Windows.Forms.Form 
    { 
     public FormListView() 
     { 
      string [] names = null; 

      this.InitializeComponent(); 

      names = Enum.GetNames(typeof(View)); 
      for (int i=0; i < names.Length; i++) 
      { 
       this.comboBox1.Items.Add(names [i]); 

       if (names [i] == this.ListView.View.ToString()) 
        this.comboBox1.SelectedIndex = i; 
      } 
     } 

     private void comboBox1_SelectedIndexChanged (object sender, EventArgs e) 
     { 
      this.ListView.View = (View) Enum.Parse(typeof(View), this.comboBox1.SelectedItem.ToString()); 
      this.ListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); 
     } 

     private void ButtonLoadImages_Click (object sender, System.EventArgs e) 
     { 
      Image image; 
      Stopwatch watch; 

      this.Enabled = false; 
      this.Cursor = Cursors.WaitCursor; 

      this.ListView.SmallImageList = null; 
      this.ListView.LargeImageList = null; 
      this.ListView.StateImageList = null; 

      while (this.ImageList.Images.Count > 0) 
      { 
       this.ImageList.Images [0].Dispose(); 
       this.ImageList.Images.RemoveAt(0); 
      } 

      this.ImageList.ImageSize = new System.Drawing.Size(256, 256); 

      watch = Stopwatch.StartNew(); 
      for (int i=0; i < 1000; i++) 
      { 
       image = new Bitmap(this.ImageList.ImageSize.Width, this.ImageList.ImageSize.Height); 
       using (Graphics graphics = Graphics.FromImage(image)) 
       { 
        graphics.Clear(Color.White); 
        graphics.DrawRectangle(Pens.Red, 10, 10, this.ImageList.ImageSize.Width - 20, this.ImageList.ImageSize.Height - 20); 
        graphics.DrawString(i.ToString(), this.Font, Brushes.Blue, 20, 20); 
       } 
       this.ImageList.Images.Add(image); 
      } 
      watch.Stop(); 

      this.ListView.SmallImageList = this.ImageList; 
      this.ListView.LargeImageList = this.ImageList; 
      this.ListView.StateImageList = this.ImageList; 

      this.Text = watch.Elapsed.TotalSeconds.ToString(); 

      this.Cursor = Cursors.Default; 
      this.Enabled = true; 
     } 

     private void ButtonLoadItems_Click (object sender, System.EventArgs e) 
     { 
      Stopwatch watch; 
      ListViewItem item; 

      this.Enabled = false; 
      this.Cursor = Cursors.WaitCursor; 

      this.ListView.Items.Clear(); 
      this.ListView.Columns.Clear(); 
      this.ListView.Columns.Add("Id", "Id"); 
      this.ListView.Columns.Add("Name", "Name"); 

      this.ListView.SmallImageList = null; 
      this.ListView.LargeImageList = null; 
      this.ListView.StateImageList = null; 

      this.ListView.BeginUpdate(); 
      watch = Stopwatch.StartNew(); 
      for (int i=0; i < 1000; i++) 
      { 
       item = new ListViewItem(); 

       item.ImageIndex = i; 
       item.Text = i.ToString(); 
       item.SubItems.Add("qwerty"); 

       this.ListView.Items.Add(item); 
      } 
      this.ListView.EndUpdate(); 

      this.ListView.SmallImageList = this.ImageList; 
      this.ListView.LargeImageList = this.ImageList; 
      this.ListView.StateImageList = this.ImageList; 

      this.ListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); 

      watch.Stop(); 

      this.Text = watch.Elapsed.TotalSeconds.ToString(); 

      this.Cursor = Cursors.Default; 
      this.Enabled = true; 
     } 
    } 
} 
相關問題