I need to select all items in a ListBox when a CheckBox is clicked. Is it possible to select all items in the ListBox using a single line of code? Or will I have to loop through all items and set selected to true for each one of them?
12 Answers
The fact is that ListBox.Items
is a plain object collection and returns plain untyped objects, which cannot be multi-selected (by default).
If you want to multi-select all items, then this will work:
for (int i = 0; i < myListBox.Items.Count;i++)
{
myListBox.SetSelected(i, true);
}

- 57,289
- 29
- 176
- 237

- 11,289
- 14
- 88
- 130
-
Assuming this logic is tied to a key combo press (ex. Ctrl+A) handled in a KeyDown event, you will also need to make sure to include e.SuppressKeyPress = true; otherwise it will revert your selection to the first "A" in the list. – Zok Wobblefotz Mar 08 '19 at 16:33
-
For large lists, one should suspend update. https://stackoverflow.com/q/15398091/340790 – JdeBP Feb 04 '21 at 13:20
As far as I can tell, using any of the .NET methods to select a large number of items is far slower than making a direct PInvoke call, passing the LB_SETSEL message (0x185) to the control, with a flag indicating whether you want to Select (1) or Unselect (0) as well as the magic value (-1) which indicates that the change should apply to all items.
[DllImport("user32.dll", EntryPoint = "SendMessage")]
internal static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam);
// Select All
SendMessage(listBox.Handle, 0x185, (IntPtr)1, (IntPtr)(-1));
// Unselect All
SendMessage(listBox.Handle, 0x185, (IntPtr)0, (IntPtr)(-1));

- 56,563
- 7
- 151
- 196
-
Nice try. It really selects all items but item enumeration fails. The problem is that after SendMessage to select all items I'm getting SelectedItems.Count shows count of all listbox items (this is right). But when I'm trying to enumerate SelectedItems - only one iteration is performed. When I perform `SelectedItems[SelectedItems.Count - 1]` IndexOutOfRange exception is thrown. Seems that items are selected but list box does not refreshes inner lists with them. To calculate `SelectedObjectCollection.Count` property getter sends another window message that returns count of all items. – oleksa Jun 06 '14 at 13:59
-
The -1 is not that magic, see [LB_SETSEL message (Windows)](http://msdn.microsoft.com/de-de/library/windows/desktop/bb761352%28v=vs.85%29.aspx). BTW: It works well with the VCL class TListBox. – Wolf Jan 15 '15 at 12:19
-
Hi, @Wolf. The term "magic" has a particular meaning in programming; see http://en.wikipedia.org/wiki/Magic_number_(programming) – EricLaw Jan 15 '15 at 17:13
-
Yes, I know. But sometimes *magic* also refers to integer literals that could better be replaced by symbolic constants, whereas some literals are preferred, for example 0. -1 is prominent for "exceptional" cases of 0-based indexing, where 0 (aka NULL) would not fit. – Wolf Jan 15 '15 at 19:47
-
Is it true, what @oleksa said, that there is a synchronization flaw between the SendMessage+LB_SETSEL method and the ListBox class? – Wolf Jan 15 '15 at 20:03
-
1@Wolf: I haven't encountered any problems (I use this technique in Fiddler). Having said that, it's probably resolvable by just allowing messages to get pumped (e.g. by calling `Application.DoEvents`) after performing the selection. – EricLaw Jan 15 '15 at 21:00
-
@EricLaw DoEvents doesn't resolve the problem. SelectedItems.Count is fine but enumerating SelectedItems returns the original selection and enumerating SelectedIndeces throws an exception. – Tony Edgecombe Nov 27 '20 at 11:22
I have seen a number of (similar) answers all which does logically the same thing, and I was baffled why yet they all dont work for me. The key is setting listbox's SelectionMode
to SelectionMode.MultiSimple
. It doesn't work with SelectionMode.MultiExtended
. Considering to select multiple items in a listbox, you will have selection mode set to multiple mode, and mostly people go for the conventional MultiExtended
style, this answer should help a lot. And ya not a foreach
, but for
.
You should actually do this:
lb.SelectionMode = SelectionMode.MultiSimple;
for (int i = 0; i < lb.Items.Count; i++)
lb.SetSelected(i, true);
lb.SelectionMode = //back to what you want
OR
lb.SelectionMode = SelectionMode.MultiSimple;
for (int i = 0; i < lb.Items.Count; i++)
lb.SelectedIndices.Add(i);
lb.SelectionMode = //back to what you want

- 70,104
- 56
- 326
- 368
-
2If you add `e.SuppressKeyPress = true;` it should work, regardless of the SelectionMode. – Razvan Socol Dec 24 '14 at 14:14
I think you have to loop here. Selecting all items at once is a pretty specific (and probably rare) use case where it simply makes no sense to offer that functionality out of the box. Furthermore, the loop will be just two lines of code anyway.

- 344,408
- 85
- 689
- 683
Within this Constructor, you need to enable the multi selection mode (MultiExtended
) of the desired text box.
public Form1()
{
InitializeComponent();
listBox1.SelectionMode = SelectionMode.MultiExtended;
listBox2.SelectionMode = SelectionMode.MultiExtended;
}
After this, use a loop to select everything:
private void selectAll_Click(object sender, EventArgs e)
{
for (int val = 0; val < listBox1.Items.Count; val++)
{
listBox1.SetSelected(val, true);
}
}
I tested it. It works. You can also use the [CTRL/SHIFT] button + left click to select the items individually.

- 3,510
- 7
- 32
- 51

- 45
- 1
- 9
I use Mika's solution, however this can be very slow if you have thousands of items. For a massive speed increase you can turn off visibility briefly. The listbox will not actually disappear during the operation as you might suspect, but the selection occurs at least 10x faster in my case.
myListBox.Visible = false;
for (int i = 0; i < myListBox.Items.Count;i++)
{
myListBox.SetSelected(i, true);
}
myListBox.Visible = true;

- 698
- 6
- 25
-
8I believe the `myListBox.Visible = false` is faster because it avoids drawing while updating. I would use the methods provided `myListBox.BeginUpdate()` and `myListBox.EndUpdate()` :) – DiogoNeves May 22 '12 at 09:09
-
2+1 for comment of DiogoNeves. It is better, because it also causes the focus to stay on the listbox. For Robin´s solution one has to call myListBox.Focus() after setting it visible again. – huha Mar 04 '14 at 08:24
In my case i had 10k+ items, the basic loop method was taking almost a minute to complete. Using @DiogoNeves answer and extending it i wanted to be able to select all (Ctrl+A) & copy (Ctrl+C). i handled this 2 ways. i used the BeginUpdate() and EndUpdate() to defer drawing but i also added a direct copy all (Ctrl+Shift+C) which doesn't even bother to select the items before copying.
private static void HandleListBoxKeyEvents(object sender, KeyEventArgs e)
{
var lb = sender as ListBox;
// if copy
if (e.Control && e.KeyCode == Keys.C)
{
// if shift is also down, copy everything!
var itemstocopy = e.Shift ? lb.Items.Cast<object>() : lb.SelectedItems.Cast<object>();
// build clipboard buffer
var copy_buffer = new StringBuilder();
foreach (object item in itemstocopy)
copy_buffer.AppendLine(item?.ToString());
if (copy_buffer.Length > 0)
Clipboard.SetText(copy_buffer.ToString());
}
// if select all
else if (e.Control && e.KeyCode == Keys.A)
{
lb.BeginUpdate();
for (var i = 0; i < lb.Items.Count; i++)
lb.SetSelected(i, true);
lb.EndUpdate();
}
}

- 1,303
- 15
- 30
this is absolutely not nice but much faster than a loop if you have many many (100+) items: Select the Listbox and simulate key input of [home] and [shift]+[end]
lb.BeginUpdate();
lb.Select();
SendKeys.Send("{Home}");
SendKeys.Send("+{End}");
lb.EndUpdate();
EDIT: works with SelectionMode.MultiExtended only I guess
DoubleEDit: also be aware that this might be too slow for code being performed with lb.selecteditems afterwards, but it may be useful for an [Select All] button that the user will click.

- 53
- 7
-
Doesn't work for me (using .Net 4.7). The listbox just flashes and that's it. – Ben_G Oct 26 '17 at 15:49
Select All is definetly available out of the box:
$("#ListBoxID option").prop("selected", true);

- 245
- 1
- 3
-
3
-
This code is also not out of the box. The listed code is jQuery and not C#/VB.NET – fujiiface Jun 14 '17 at 22:27
-
I know this question is tagged with .NET 2.0 but if you have LINQ available to you in 3.5+, you can do the following:
ASP.NET WebForms
var selected = listBox.Items.Cast<System.Web.UI.WebControls.ListItem>().All(i => i.Selected = true);
WinForms
var selected = listBox.SelectedItems.Cast<int>().ToArray();

- 1,262
- 11
- 15
-
Nope - I get The type or name ListItem could not be found. (Are you missing a Using directive or assembly reference). – Ben_G Oct 26 '17 at 15:50
-
Seems a bit excessive to downvote the solution instead of working with the person to figure out why the solution might not work for you. Do you have the mentioned missing Using directive `using System.Web.UI.WebControls;`? Are you referencing the assembly?Answer updated to reference the assembly. – fujiiface Oct 26 '17 at 16:28
-
Sorry fujiface - I upvoted you again. I initially thought that you wrote your post back in 2014 so I wasn't expecting a response. I can't seem to access System.Web.UI.WebControls. All I can see is System.Web. And I tried to add a reference to it but it doesn't show up there either. Maybe it was deprecated in 4.7? I looked for a NuGet package with that name and that's not there either. – Ben_G Oct 26 '17 at 16:35
-
And looking at the docs on MSDN I see a System.Web.UI.Design.WebControls Namespace, but I can't seem to access it in my code. – Ben_G Oct 26 '17 at 16:44
-
No problem @Ben_G. That's a good point. Depending on what kind of project you have (mine is web based and the OP is using WinForms circa 2009) you might not be able to access server controls. I didn't really specify the ListItem type since the question is tagged with WinForms and looking closer at my answer, it might need to be adjusted further to be within the WinForms context. – fujiiface Oct 26 '17 at 16:46
-
I added nawfal's idea to what I had already, which was also with 'BeginUpdate'. Additionaly the view position is maintained too, as the user would expect. For me this seems to solve all problems now:
public void SelectAll()
{
bool prevBusy = MouseHelper.IsBusy;
MouseHelper.IsBusy = true;
int topIndex = TopIndex;
// BUG: In 'SelectionMode.MultiExtended' the box gets crazy
SelectionMode previousMode = this.SelectionMode;
this.SelectionMode = SelectionMode.MultiSimple;
this.BeginUpdate();
for (int i = 0; i < Items.Count; i++)
{
SelectedIndices.Add(i);
}
this.EndUpdate();
this.SelectionMode = previousMode;
TopIndex = topIndex;
MouseHelper.IsBusy = prevBusy;
}

- 508
- 4
- 7
private void Button_Click(object sender, RoutedEventArgs e)
{
listbox.SelectAll();
}

- 1
-
-
There is no SelectAll method in the WinForms ListBox. You are probably thinking about the WPF ListBox, but this question is tagged "winforms" and ".net-2.0". – Razvan Socol Dec 24 '14 at 13:19