Reputation: 193
Given -
1> An empty ListView - 'listView1'.
2> A sorted List of 30,000 strings - 'myList'.
To perform - To add several thousand items in the listview1 from myList in an optimized way.
// Since default sortOrder is set to Ascending, everytime an element is added in the listview, it will sort the entire listview. If there are several thousand elements in the list, then this could cause serious speed delays.
this.listView1.Sorting = System.Windows.Forms.SortOrder.Ascending;
protected void addbutton_Click(object sender, System.EventArgs e)
{
var watchFinal = System.Diagnostics.Stopwatch.StartNew();
var myList = new List<string>();
var items = new List<ListViewItem>();
String tempStr;
int count = 30000;
ListViewItem lvi = null;
// Adding items in the List and then sorting it.
for (int i = 0; i < count; i++)
{
tempStr = "Nikhil" + i.ToString();
myList.Add(tempStr);
}
myList.Sort();
// BeginUpdate and Endupdate will stop the draw untill everything is loaded in added listview.
listView1.BeginUpdate();
listView1.Sorting= SortOrder.None;
foreach (String str in myList)
{
lvi = new ListViewItem(str);
listView1.Items.Add(lvi);
}
listView1.EndUpdate();
listView1.Sorting= SortOrder.Ascending;
// Once all elements are added, then they will be sorted in one go.
watchFinal.Stop();
var elapsedMs = watchFinal.ElapsedMilliseconds;
var elapsedSeconds = elapsedMs / 1000;
var elapsedMinutes = elapsedSeconds / 60;
Console.WriteLine("count: " + count + "; Seconds: " + elapsedSeconds + "; milliseconds: " + elapsedMs + "; Minutes: " + elapsedMinutes);
}
results -
count: 30000; Seconds: 2; milliseconds: 2094; Minutes: 0
count: 60000; Seconds: 4; milliseconds: 4540; Minutes: 0
count: 120000; Seconds: 9; milliseconds: 9774; Minutes: 0
I need optimize this code, and hence the timings. Any suggestions will be appreciated.
Note -
Since the items in myList are already sorted, when they are added to the listview, they're already sorted. So we don't really need to sort them again.
However, I need to keep the SortOrder of listview to Ascending by default. But if I mention this - "listView1.Sorting= SortOrder.Ascending;", in the add method, it will in the end, always sort it once again.
what's the best way to handle this?
We can use AddRange - which states that "If the ListView.Sorting property is set to a value other than SortOrder.None or if the ListViewItemSorter property is set, the list is sorted after the items are added." But isn't it doing exactly what I've implemented?
How to disable automatic sorting in listview? If I want to remove "listView1.Sorting= SortOrder.Ascending;" from the below code, so the method doesn't sort the list again, but I still want to keep the list's default SortOrder to Ascending, so if we do any other operation, the list remains sorted, then what can be done?
Upvotes: 0
Views: 1631
Reputation: 71
As I understand you want to add 120000 items to your listview. It is A LOT! In this case I would have used VirtualMode option of listview. Here is example.
In this case other logic probably will have changed:
We no longer have the Items collection which would throw exceptions when we would try to use it. The SelectedItems collection is also gone. Instead the SelectedIndices is your friend. Well nearly I found that my items were deselected without beeing notified by the ItemSelectionChanged event so I stored the last selected item index by myself when the SelectedIndicies collection was not empty.
Upvotes: 0
Reputation: 819
Look into the AddRange(ListViewItem[])
method of ListView.ListViewItemCollection
.
It would be more efficient to sort your items before calling EndUpdate()
, and with the AddRange
method it will automatically sort your items after adding them (provided that you set the sorting order beforehand).
If you didn't want to do this then another small increase in efficiency would be to do:
listView1.Items.Add(new ListViewItem(str));
rather than:
lvi = new ListViewItem(str);
listView1.Items.Add(lvi);
Upvotes: 0