Мне нужно выбрать все элементы в ListBox при щелчке по CheckBox. Можно ли выбрать все элементы в ListBox, используя одну строку кода? Или мне придется перебирать все элементы и задавать значение true для каждого из них?
Спасибо:)
Мне нужно выбрать все элементы в ListBox при щелчке по CheckBox. Можно ли выбрать все элементы в ListBox, используя одну строку кода? Или мне придется перебирать все элементы и задавать значение true для каждого из них?
Спасибо:)
Думаю, вам нужно зациклиться здесь. Выбор всех элементов сразу - довольно конкретный (и, вероятно, редкий) вариант использования, когда просто не имеет смысла предлагать эту функциональность из коробки. Более того, цикл будет всего лишь двумя строками кода.
Дело в том, что ListBox.Items
представляет собой простой коллекцию объектов и возвращает простые нетипизированные объекты, которые не могут быть многократно выбраны (по умолчанию).
Если вы хотите многократно выбирать все элементы, это будет работать:
for (int i = 0; i < myListBox.Items.Count;i++)
{
myListBox.SetSelected(i, true);
}
Насколько я могу судить, использование любого из методов .NET для выбора большого количества элементов намного медленнее, чем прямой вызов PInvoke, передавая сообщение LB_SETSEL (0x185) элементу управления с флагом, указывающим, вы хотите выбрать (1) или "Отменить выбор" (0), а также магическое значение (-1), которое указывает, что изменение должно применяться ко всем элементам.
[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));
Я видел несколько (похожих) ответов на все, что логически одно и то же, и я был озадачен, почему все же они не работают для меня. Ключ устанавливает список SelectionMode
- SelectionMode.MultiSimple
. Он не работает с SelectionMode.MultiExtended
. Учитывая выбор нескольких элементов в списке, у вас будет режим выбора, установленный в несколько режимов, и в основном люди идут на обычный стиль MultiExtended
, этот ответ должен многое помочь. И ya не a foreach
, а for
.
Вы должны это сделать:
lb.SelectionMode = SelectionMode.MultiSimple;
for (int i = 0; i < lb.Items.Count; i++)
lb.SetSelected(i, true);
lb.SelectionMode = //back to what you want
ИЛИ
lb.SelectionMode = SelectionMode.MultiSimple;
for (int i = 0; i < lb.Items.Count; i++)
lb.SelectedIndices.Add(i);
lb.SelectionMode = //back to what you want
Я использую решение Mika, однако это может быть очень медленным, если у вас есть тысячи предметов. Для массового увеличения скорости вы можете временно отключить видимость. Список не будет исчезать во время операции, как вы могли бы подозревать, но выбор происходит как минимум в 10 раз быстрее в моем случае.
myListBox.Visible = false;
for (int i = 0; i < myListBox.Items.Count;i++)
{
myListBox.SetSelected(i, true);
}
myListBox.Visible = true;
Внутри этого конструктора вам нужно включить режим множественного выбора (MultiExtended
) нужного текстового поля.
public Form1()
{
InitializeComponent();
listBox1.SelectionMode = SelectionMode.MultiExtended;
listBox2.SelectionMode = SelectionMode.MultiExtended;
}
После этого используйте цикл, чтобы выделить все:
private void selectAll_Click(object sender, EventArgs e)
{
for (int val = 0; val < listBox1.Items.Count; val++)
{
listBox1.SetSelected(val, true);
}
}
Я протестировал его. Оно работает. Вы также можете использовать кнопку [CTRL/SHIFT] + левый клик, чтобы выбрать элементы отдельно.
Выбрать все определенно доступно из коробки:
$("#ListBoxID option").prop("selected", true);
Я знаю, что этот вопрос отмечен .NET 2.0, но если у вас есть LINQ, доступный для вас в версии 3.5+, вы можете сделать следующее:
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();
Это абсолютно не приятно, но намного быстрее, чем цикл, если у вас много много (100+) предметов: Выберите Listbox и имитируйте ввод ключа [home] и [shift] + [end]
lb.BeginUpdate();
lb.Select();
SendKeys.Send("{Home}");
SendKeys.Send("+{End}");
lb.EndUpdate();
EDIT: работает с SelectionMode.MultiExtended только я думаю
DoubleEDit: также помните, что это может быть слишком медленным для выполнения кода с помощью lb.selecteditems, но может быть полезно для кнопки [Выбрать все], которую пользователь нажмет.
В моем случае у меня было 10k+ элементов, метод основного цикла занимал почти минуту, чтобы завершить. Используя ответ @DiogoNeves и расширяя его, я хотел иметь возможность выделить все (Ctrl + A) и скопировать (Ctrl + C). Я справился с этим 2 способами. я использовал BeginUpdate() и EndUpdate(), чтобы отложить рисование, но я также добавил прямую копию всех (Ctrl + Shift + C), которая даже не удосуживается выбрать элементы перед копированием.
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();
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
listbox.SelectAll();
}