web-dev-qa-db-fra.com

ListBox sélectionner tous les éléments

Je dois sélectionner tous les éléments d'un ListBox lorsqu'un clic est effectué sur un CheckBox. Est-il possible de sélectionner tous les éléments de la liste en utilisant une seule ligne de code? Ou devrais-je parcourir tous les éléments et définir la sélection à true pour chacun d'entre eux?

Merci :)

23
Rashmi Pandit

Je pense que vous devez faire une boucle ici. La sélection de tous les éléments à la fois est un cas d'utilisation assez spécifique (et probablement rare) où il n'a aucun sens d'offrir cette fonctionnalité immédiatement. De plus, la boucle ne comportera de toute façon que deux lignes de code.

4
Joey

Le fait est que ListBox.Items est une collection d'objets standard et renvoie des objets non typés, qui ne peuvent pas être sélectionnés plusieurs fois (par défaut).

Si vous voulez sélectionner tous les éléments de manière multiple, cela fonctionnera:

   for (int i = 0; i < myListBox.Items.Count;i++)
   {
       myListBox.SetSelected(i, true);
   }
60
Mehdi LAMRANI

Autant que je sache, l’utilisation de l’une des méthodes .NET pour sélectionner un grand nombre d’éléments est beaucoup plus lente que de passer un appel direct PInvoke, en transmettant le message LB_SETSEL (0x185) au contrôle, avec un indicateur indiquant si vous voulez ou non. Sélectionnez (1) ou Désélectionnez (0) ainsi que la valeur magique (-1) qui indique que le changement doit s’appliquer à tous les éléments.

  [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
EricLaw

J'ai vu un certain nombre de réponses (similaires) toutes ce qui fait logiquement la même chose, et j'ai été déconcerté de savoir pourquoi elles ne fonctionnent pas toutes pour moi. La clé est de définir la variable SelectionMode de la listbox sur SelectionMode.MultiSimple. Cela ne fonctionne pas avec SelectionMode.MultiExtended. Si vous envisagez de sélectionner plusieurs éléments dans une zone de liste, le mode de sélection sera défini sur plusieurs modes et la plupart des gens optent pour le style MultiExtended conventionnel. Cette réponse devrait beaucoup vous aider. Et vous n'êtes pas un foreach, mais for.

Vous devriez réellement faire ceci: 

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
7
nawfal

J'utilise la solution de Mika, mais cela peut être très lent si vous avez des milliers d'articles. Pour une augmentation de vitesse massive, vous pouvez désactiver la visibilité brièvement. La liste déroulante ne disparaîtra pas pendant l'opération, contrairement à ce que vous pourriez penser, mais la sélection est effectuée au moins 10 fois plus vite dans mon cas.

myListBox.Visible = false;
for (int i = 0; i < myListBox.Items.Count;i++)
{
    myListBox.SetSelected(i, true);
}
myListBox.Visible = true;
1
Robin

Dans ce constructeur, vous devez activer le mode de sélection multiple (MultiExtended) de la zone de texte souhaitée.

public Form1()
{
    InitializeComponent();
    listBox1.SelectionMode = SelectionMode.MultiExtended;
    listBox2.SelectionMode = SelectionMode.MultiExtended;
}

Après cela, utilisez une boucle pour tout sélectionner:

private void selectAll_Click(object sender, EventArgs e)
{
    for (int val = 0; val < listBox1.Items.Count; val++)
    {
        listBox1.SetSelected(val, true);
    }
}

Je l'ai testé. Ça marche. Vous pouvez également utiliser le bouton [CTRL/SHIFT] + clic gauche pour sélectionner les éléments individuellement.

1
Rhonwen Van Druten

Je sais que cette question porte la mention .NET 2.0, mais si LINQ est disponible dans la version 3.5+, vous pouvez procéder comme suit:

Formulaires Web ASP.NET

var selected = listBox.Items.Cast<System.Web.UI.WebControls.ListItem>().All(i => i.Selected = true);

WinForms

var selected = listBox.SelectedItems.Cast<int>().ToArray();
1
fujiiface

Tout sélectionner est définitivement disponible:

$("#ListBoxID option").prop("selected", true);
1
jfatal

ce n’est absolument pas agréable, mais bien plus rapide qu’une boucle si vous avez beaucoup (plus de 100) éléments: Sélectionnez la zone de liste et simulez la saisie de touche [home] et [shift] + [end]

lb.BeginUpdate();
lb.Select();
SendKeys.Send("{Home}");
SendKeys.Send("+{End}");
lb.EndUpdate();

EDIT: fonctionne avec SelectionMode.MultiExtended seulement je suppose

DoubleEDit: sachez également que cela peut être trop lent pour que le code soit ensuite exécuté avec lb.selected, mais cela peut être utile pour un bouton [Tout sélectionner] sur lequel l'utilisateur cliquera.

0
doomi

Dans mon cas, j'avais 10k + items, la méthode de base de la boucle prenait presque une minute à compléter. En utilisant @DiogoNeves, je voulais pouvoir tout sélectionner (Ctrl + A) et copier (Ctrl + C). J'ai géré cela de 2 façons. J'ai utilisé BeginUpdate () et EndUpdate () pour différer le dessin, mais j'ai également ajouté une copie directe à tous (Ctrl + Maj + C) qui ne prend même pas la peine de sélectionner les éléments avant de les copier.

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();
    }
}
0
Justin