Winforms 为什么带有ImageList的ListView非常慢?(关于:1000个缩略图)

Winforms 为什么带有ImageList的ListView非常慢?(关于:1000个缩略图),winforms,listview,thumbnails,imagelist,Winforms,Listview,Thumbnails,Imagelist,我试图使用ListView组件来显示大约1000个图像缩略图,但我遇到了一些性能问题 首先,我创建了一个包含1000个图像的ImageList。这是闪电般的速度,需要不到一秒钟的时间 但是,一旦我将ImageList分配给我的ListView,大约需要10秒以上的时间 例如: ImageList _imgList = GetMyImageList(); // takes under 1 second ListView _lstView = new ListView(); lstView.Lar

我试图使用ListView组件来显示大约1000个图像缩略图,但我遇到了一些性能问题

首先,我创建了一个包含1000个图像的ImageList。这是闪电般的速度,需要不到一秒钟的时间

但是,一旦我将ImageList分配给我的ListView,大约需要10秒以上的时间

例如:

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

我能做些什么来提高性能吗?“我的图像列表”包含已调整为缩略图大小(197x256像素)的图像,因此这不是问题所在。。。(创建我的图像列表最多只需要1秒)。

列表视图中的数据是否经常更改?您是否经常加载新图像列表

我尝试了您的场景,获得了几秒钟的加载时间(因为我生成了随机图像),但在更改列表视图
[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;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用系统图;
使用System.Linq;
使用System.Windows.Forms;
命名空间Windows窗体应用程序10
{
公共部分类FormListView:
System.Windows.Forms.Form
{
公共表单列表视图()
{
字符串[]名称=null;
this.InitializeComponent();
names=Enum.GetNames(typeof(View));
for(int i=0;i0)
{
this.ImageList.Images[0].Dispose();
this.ImageList.Images.RemoveAt(0);
}
this.ImageList.ImageSize=新系统.Drawing.Size(256,256);
watch=Stopwatch.StartNew();
对于(int i=0;i<1000;i++)
{
image=新位图(this.ImageList.ImageSize.Width,this.ImageList.ImageSize.Height);
使用(Graphics=Graphics.FromImage(image))
{
图形。清晰(颜色。白色);
graphics.DrawRectangle(Pens.Red,10,10,this.ImageList.ImageSize.Width-20,this.ImageList.ImageSize.Height-20);
graphics.DrawString(i.ToString(),this.Font,brush.Blue,20,20);
}
this.ImageList.Images.Add(image);
}
看,停;
this.ListView.SmallImageList=this.ImageList;
this.ListView.LargeImageList=this.ImageList;
this.ListView.StateMageList=this.ImageList;
this.Text=watch.eassed.TotalSeconds.ToString();
this.Cursor=Cursors.Default;
this.Enabled=true;
}
私有无效按钮默认项单击(对象发送者,System.EventArgs e)
{
秒表;
ListViewItem项目;
此.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();
对于(int i=0;i<1000;i++)
{
item=新的ListViewItem();
item.ImageIndex=i;
item.Text=i.ToString();
项目。子项目。添加(“qwerty”);
this.ListView.Items.Add(item);
}
this.ListView.EndUpdate();
this.ListView.SmallImageList=this.ImageList;
this.ListView.LargeImageList=this.ImageList;
this.ListView.StateMageList=this.ImageList;
this.ListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
看,停;
this.Text=watch.eassed.TotalSeconds.ToString();
this.Cursor=Cursors.Default;
this.Enabled=true;
}
}
}

列表视图中的数据是否经常更改?您是否经常加载新图像列表

我尝试了您的场景,获得了几秒钟的加载时间(因为我生成了随机图像),但在更改列表视图
[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;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用系统图;
使用System.Linq;
使用System.Windows.Forms;
命名空间Windows窗体应用程序10
{
公共部分类FormListView:
System.Windows.Forms.Form
{
公共表单列表视图()
{
字符串[]名称=null;
this.InitializeComponent();
names=Enum.GetNames(typeof(View));
for(int i=0;i