The
Set the VirtualMode property to True will place ListView in virtual mode. Control no longer uses the Collection.add () method to add data, instead using Retrievevirtualitem (occurs when the ListView are in virtual mode and requires a Li Stviewitem.) and Cachevirtualitems two events, Retrievevirtualitem can also be used alone, Cachevirtualitems this event is intended to facilitate the programmer to manipulate the buffer set, its parameters Cachevirtualitems EventArgs has startindex and endindex two attributes in virtual mode.
in virtual mode, the performance can be greatly improved by getting the required data from the buffer to load. In other cases, the value of the ListViewItem object may need to be recalculated frequently, and doing so for the entire collection will produce unacceptable performance.
Sample code:
using system;
using system.collections.generic;
using system.windows.forms;
namespace winformtest { public partial class form1 : form { private List<ListViewItem>
myCache; public form1 () { initializecomponent () myCache = new List<
Listviewitem> (); } private Void form1_load (object sender, eventargs e) { listview1.view = view .Details; listview1.virtualmode = true
; listview1.retrievevirtualitem +=
new retrievevirtualitemeventhandler (Listview1_retrievevirtualitem); } void Listview1_retrievevirtualitem (object sender, retrievevirtualitemeventargs e) { if (mycache != null ) { e.item
= myCache[e.ItemIndex]; } else { //a cache
miss, so create a new listviewitem and pass it back. int x
= e.ItemIndex * e.ItemIndex; e.item =
new listviewitem (X.tostring ()); } } Private void button1_click (object sender, eventargs e) { list<student> list = getstudentlist
(); foreach (var item in list) { listviewitem listviewitem =
new listviewitem (); Listviewitem.subitems[0]. Text = item.
Name; LISTVIEWITEM.SUBITEMS.ADD (item.
SEX); mycache.add (
ListViewItem); } listview1.virtuallistsize = mycache.count; } private List<student> getstudentlist () { list<student> list = new list
<Student> (); for (int i = 0; i < 2000; i++) { Student stu = new student { name = "Student" + i, Sex = "male
" }; list.
ADD (Stu); }
return list; } private Void button2_click (object sender, eventargs e) { ListViewItem
Listitem = new listviewitem (); listitem.subitems[0].
text = "female";
listitem.subitems.add ("haha");
mycache.add (ListItem); listView1.VirtualListSize =
Mycache.count; &nbSp; listview1.invalidate (); } public Class student { public string sex { get; set; } public string name { get; set; }  }}
Summarize
(1) must set VirtualMode to True and set virtuallistsize size
(2) Binding the event Retrievevirtualitem
(3) If the data is updated in the middle, you need to reset the virtuallistsize and call the Invalidate () method
(4) Disable SelectedItem, in which the use of SelectedItem will produce an exception, you can use the following method instead
Private list<listviewitem> Findselectedall ()
{
list<listviewitem> r = new list<listviewitem& gt; ();
foreach (int item in listview1.selectedindices)
{
r.add (Bufferitems[item]);
} return
R;
}
WinForm ListView Loads large amounts of data without paging
WinForm's ListView can cause flicker when loading large amounts of data, while data loading is slow. If you have more than thousands of data in your list and do not do special processing or use a normal ListView.Items.Add (), it is estimated that your users will complain.
Here's how to fix it:
1. Use ListView1.Items.AddRange () instead of add
This method requires putting the data into a cached array, then calling AddRange to join the ListView one at a time, and using a single counter to record the amount of cache to be added as follows:
ListView1.Items.Clear ();
if (Vlist.count > 0)
{
int Indexi = 0;
list<listviewitem> Listbuffer = new list<listviewitem> ();
foreach (var item in Vlist)
{
ListViewItem li = new ListViewItem ();
Li. ImageIndex = 0;
Li. Subitems[0]. Text = Item. Name;
Li. Tag = Item;
Li. ForeColor = Item. Status = 0? Color.Green:Color.Red;
Listbuffer.add (LI);
if (indexi++% 1000 = 0)
{
ListView1.Items.AddRange (Listbuffer.toarray ());
Listbuffer.clear ();
}
if (indexi% 50 = 0)
{
Application.doevents ();
}
}
ListView1.Items.AddRange (Listbuffer.toarray ());
}
This reduces the number of ListView flashes, and the amount of data is not very large when it works.
2, Custom ListView class
The following class is widely circulated on the internet, although solve the problem of ListView flashing, but in the open speed and the original no difference, but also bring a problem is if the program switch to other ListView, the data will continue to forget the original ListView Add, until the data is fully added to complete.
public class ListViewLargeData:System.Windows.Forms.ListView
{
Public Listviewlargedata ()
{
This. SetStyle (Controlstyles.optimizeddoublebuffer | Controlstyles.allpaintinginwmpaint, True);
This. SetStyle (Controlstyles.enablenotifymessage, true);
}
protected override void Onnotifymessage (message m)
{
if (m.msg!= 0x14)
{
Base. Onnotifymessage (m);
}
}
}
3, open the ListView virtualmode mode
This is also the recommended way to do this article, you can achieve no flicker effect, and open fast. Often a good effect of the problem is that the code is more complex, the specific wording can see the official example http://msdn.microsoft.com/zh-cn/library/ System.windows.forms.listview.virtualmode.aspx, the following points to note:
(1) must set VirtualMode to True and set virtuallistsize size
Listview1.virtualmode = true;
Listview1.virtuallistsize = Bufferitems.count;
Listview1.retrievevirtualitem + = new Retrievevirtualitemeventhandler (Listview_retrievevirtualitem);
(2) Bind the event to ListView compute the item
void Listview_retrievevirtualitem (object sender, Retrievevirtualitemeventargs e)
{
E.item = M_hlistviewitems[e.itemindex];
}
(3) If the data is updated in the middle, you need to reset the virtuallistsize and call the Invalidate () method (this method does not have to be expert pointing).
Listview1.virtuallistsize = Bufferitems.count;
Listview1.invalidate ();
(4) Disable SelectedItem, in which the use of SelectedItem will produce an exception, you can use the following method instead
Private list<listviewitem> Findselectedall ()
{
list<listviewitem> r = new list<listviewitem> ();
foreach (int item in listview1.selectedindices)
{
R.add (Bufferitems[item]);
}
return R;
}