现在的位置: 首页 > 综合 > 正文

防止闪烁的ListView显示方案

2013年06月29日 ⁄ 综合 ⁄ 共 1451字 ⁄ 字号 评论关闭

The resolution of ListView Blink

防止闪烁的ListView显示方案

相信做Win Form程序的朋友们一定遇到过在ListView中插入数据时,界面上一直在闪烁,而且速度很慢的情况吧。究其原因,还是在Windows消息机制没有使用好的原因。

本文对于ListView闪烁的原因,进行探究,并对于不同种的情况给出解决方案。

闪烁的原因

ListView闪烁的原因有以下几点或几种情况:
1:在数据多次插入间,存在时间间隔。
2:使用普通的Items.Add方法插入的数据量过大。
3:界面上有多个ListView在进行数据插入。

最根本的原因是因为,每次调用ListView实例进行插入的时候,都需要向系统发送一个窗口消息(相信做C++的朋友应该很清楚),然后窗口接到消息就会刷新对应控件的界面。所以,如果间隔时间长,或插入次数多,一定会闪烁的。

防止闪烁的ListView

解决方案

源码中实例的解决方案:

ListViewItem lvi;

            ListViewItem[] lvitems1 = new ListViewItem[10000];

            for (int i = 0; i < 10000; i++)
            {
                lvi = new ListViewItem(new string[] { i.ToString(), "22" });
                lvitems1[i] = lvi;
            }

            listViewTest.Items.AddRange(lvitems1);

更通用的解决方法:

// create a temp dataTable to store data
            DataTable dt = new DataTable();
            DataRow dr;
            dt.Columns.Add("ID", typeof(String));
            dt.Columns.Add("Name", typeof(String));
            dt.Columns.Add("Class", typeof(String));
            dt.Columns.Add("Lesson", typeof(String));

	        foreach(item in dataSource)
	        {
                    dr = dt.NewRow();
                    dr[0] = item.ID; // ID 
                    dr[1] = item.Name;  // Name
                    dr[2] = item.Class;  // Class
                    dr[3] = item.Lesson;  // Lesson

                    dt.Rows.Add(dr);

	        }

            // loop the temp table , and insert to ListView

            int i = 0;
            while(iint iSize = (dt.Rows.Count-i)>1000?1000:(dt.Rows.Count-i);
                            
                ListViewItem lvi;

                ListViewItem[] lvitems = new ListViewItem[iSize];

                for (int j = 0; j < iSize; j++)
                {
                    lvi = new ListViewItem(new string[] { dt.Rows[i+j][0].ToString(), dt.Rows[i+j][1].ToString(), dt.Rows[i+j][2].ToString(), dt.Rows[i+j][3].ToString() });
                    lvitems[i] = lvi;
                }

                listViewTest.Items.AddRange(lvitems);

                i = i + iSize;
            }

主要思路是,建一个临时的Table,然后,把数据插入到这个临时表中;在处理结束之后,使用Items.AddRange方法把数据分块插入到ListView。

演示结果

插入性能会提高3倍

抱歉!评论已关闭.