Poor performace when selecting all items in a listbox?

  • Thread starter Thread starter Duncan Smith
  • Start date Start date
D

Duncan Smith

So far, the quikest way I have found to select all items in a list box
is to turn off updates, set a wait cusror and then call SetSelected on
each item (see below), but it's too slow when the control is populated
with tens of thousands of items.

Ideally the wait-cursor shouldn't be needed as I hadn't anticipated a
select-all operation taking a noticeable amount of time. Has anyone
found a way to make this appear instantaneous as it would be in MFC?

Many thanks,

Duncan.

private void selectAllToolStripMenuItem_Click(object sender, EventArgs
e)
{
if( Messages.Items.Count > 0 )
{
Messages.BeginUpdate();

Cursor prevCursor = Cursor;
Cursor = Cursors.WaitCursor;

for( int ii = 0; ii < Messages.Items.Count; ++ii )
{
Messages.SetSelected(ii, true);
}

Messages.EndUpdate();

Cursor = prevCursor;
}
}
 
Has anyone found a way to make this appear instantaneous as it would be in MFC?
for( int ii = 0; ii < Messages.Items.Count; ++ii )
{
Messages.SetSelected(ii, true);
}


VERY new to C# and don't know Framework library (and therefore
implications) but following code worked much better for 5000 list
items/rows compared to "SetSelected"-

for( int ii = 0; ii < Messages.Items.Count; ++ii )
{
Messages.SelectedIndex = ii;
}

Thanks,
Neel.
 
You could try using a ListView instead of a ListBox.
Then replace
Messages.SetSelected(ii, true);
with
Messages.Items[ii].Selected = true;
There are a few other properties you have to set on a ListView to make
it look like a ListBox. And the Items array is a different type of
object which is a bit of a pain.
for( int ii = 0; ii < Messages.Items.Count; ++ii )
{
Messages.SelectedIndex = ii;
}

Um, I don't think that code snippet is quite the same as the original.
He wanted to select all, not select all one at a time.
 
You could try using a ListView instead of a ListBox.
Then replace
Messages.SetSelected(ii, true);
with
Messages.Items[ii].Selected = true;
There are a few other properties you have to set on a ListView to make
it look like a ListBox. And the Items array is a different type of
object which is a bit of a pain.
for( int ii = 0; ii < Messages.Items.Count; ++ii )
{
Messages.SelectedIndex = ii;
}

Um, I don't think that code snippet is quite the same as the original.
He wanted to select all, not select all one at a time.

Thanks, I had to go with a ListView in the end anyway for the
EnsureVisible() method, so the most recently added item could be made
to be scrolled into view.

I found the quickest way to select all items was to use SendKeys(), I
hope it's not considered bad practice, certainly seems the most
responsive course given a densely populated control (see snippet
below):

Regards,

Duncan.

/// <summary>
/// Selects all items from the messages listview
/// </summary>
/// <param name="sender">Calling object</param>
/// <param name="e">args</param>
private void selectAllToolStripMenuItem_Click(object sender,
EventArgs e)
{
if (Messages2.Items.Count > 0)
{
Messages2.Focus();
SendKeys.SendWait("{HOME}");
SendKeys.SendWait("+{END}");
}
}
 
I found the quickest way to select all items was to use SendKeys()

Yes, I had thought of that but I didn't know how to do that in new
framework (used of doing it in MFC), but, thanks to you, I know now.
In addition to that, the time that it takes to select _all_ items, no
matter how many, with HOME + END characters when done manually through
keyboard, didn't feel right. So, when with your example I tried it
with 10,000 items. With "Messages.SelectedIndex = ii;", if you had a
event handler defined for "SelectedIndexChanged" it will be called for
every item. But, with "SendKeys" it will be called _only_ for two
items (first and last). For some of the applications it would be okay,
for some of them its not I guess.

Thanks,
Neel.
 
Back
Top