ListBox выбрать все элементы - PullRequest
24 голосов
/ 01 июня 2009

Мне нужно выбрать все элементы в ListBox при нажатии CheckBox. Можно ли выбрать все элементы в ListBox, используя одну строку кода? Или мне придется пройтись по всем элементам и установить для каждого из них значение true?

Спасибо:)

Ответы [ 12 ]

62 голосов
/ 01 декабря 2010

Дело в том, что ListBox.Items является коллекцией простых объектов и возвращает простые нетипизированные объекты, которые не могут быть выделены несколькими (по умолчанию).

Если вы хотите выбрать все элементы одновременно, это будет работать:

   for (int i = 0; i < myListBox.Items.Count;i++)
   {
       myListBox.SetSelected(i, true);
   }
8 голосов
/ 23 октября 2012

Насколько я могу судить, использование любого из методов .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));
8 голосов
/ 21 декабря 2011

Я видел несколько (похожих) ответов на все, что логически делает одно и то же, и я был озадачен, почему все же они не работают на меня. Ключом является установка списка SelectionMode на SelectionMode.MultiSimple. Это не работает с SelectionMode.MultiExtended. Учитывая выбор нескольких элементов в списке, у вас будет режим выбора нескольких режимов, и в основном люди выбирают обычный стиль MultiExtended, этот ответ должен сильно помочь. И ты не 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

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
5 голосов
/ 01 июня 2009

Я думаю, что вы должны зациклить здесь. Выбор всех элементов одновременно является довольно специфическим (и, вероятно, редким) случаем использования, когда просто не имеет смысла предлагать эту функциональность из коробки. Кроме того, цикл в любом случае будет состоять из двух строк кода.

1 голос
/ 15 июня 2017

Я знаю, что этот вопрос помечен как .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();
1 голос
/ 16 февраля 2017

Выбрать все определенно доступно из коробки:

$("#ListBoxID option").prop("selected", true);
1 голос
/ 02 июля 2016

В этом конструкторе необходимо включить режим множественного выбора (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] + щелчок левой кнопкой мыши , чтобы выбрать элементы по отдельности.

1 голос
/ 27 апреля 2012

Я использую решение Мики, однако это может быть очень медленным, если у вас есть тысячи предметов. Для значительного увеличения скорости вы можете на короткое время отключить видимость. Во время операции список не исчезнет, ​​как вы, возможно, подозреваете, но в моем случае выбор происходит по крайней мере в 10 раз быстрее.

myListBox.Visible = false;
for (int i = 0; i < myListBox.Items.Count;i++)
{
    myListBox.SetSelected(i, true);
}
myListBox.Visible = true;
0 голосов
/ 25 марта 2019

Я добавил идею nawfal к тому, что у меня уже было, что также было с BeginUpdate Кроме того, позиция просмотра также поддерживается, как и ожидал пользователь. Для меня это, кажется, решает все проблемы сейчас:

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;
}
0 голосов
/ 31 января 2019

В моем случае у меня было 10 000+ элементов, основной метод цикла занимал почти минуту. Используя ответ @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();
    }
}
...