为什么带有ImageList的ListView非常慢? (re:1000+缩略图)

时间:2011-09-06 15:28:31

标签: winforms listview thumbnails imagelist

我正在尝试使用ListView组件来显示大约1,000张图片缩略图,而且我遇到了一些性能问题。

首先,我创建一个包含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秒钟。)

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;
        }
    }
}