2010-12-08 16 views
4

J'ai un contrôle CheckedListBox sur mon formulaire, et je veux que l'utilisateur puisse seulement vérifier un élément à la fois dans cette liste (si bien que je voudrais quelque chose qui imiterait un "RadioListBox" "). Est-ce possible avec CheckedListBox ou est-ce que je devrais improviser le faire d'une autre manière?Winforms checkedlistbox cochez un élément

La CheckedListBox est peuplée de la charge de forme par des éléments de chargement à partir d'une base de données, dans le cas où ce qui importe.

Merci

Modifier

Je pense que je devrais préciser, je ne cherche pas à limiter la quantité d'un utilisateur peut choisir (la propriété SelectionMode), plutôt combien ils peuvent vérifier.

+0

Pourquoi utiliser une liste déroulante cochée alors. Vous pouvez simplement utiliser une simple liste. –

+0

L'utilisateur a spécifiquement demandé de pouvoir "vérifier" malheureusement. S'il n'y a pas de moyen facile de limiter le nombre d'éléments pouvant être vérifiés en même temps, je vais simplement utiliser une listbox normale comme vous le dites. – AndrewC

+0

Utilisez plutôt un contrôle ComboBox. DropDownStyle = Simple si vous voulez vraiment une liste. –

Répondre

3

Vous pouvez le faire en ajoutant un contrôle d'événement sur CheckedListBox pour la fonction ItemCheck et l'utilisation comme ceci:

private static bool checkIfAllowed(CheckedListBox listBox) { 
     if (listBox.CheckedItems.Count > 0) { 
      return false; 
     } 
     return true; 
    } 

Ensuite, dans le cas où vous aurait aimé:

if (checkIfAllowed) { 
    ... 
    } else { 

    } 

De plus vous pouvez améliorer cela en ajoutant une autre fonction/méthode qui désélectionnera tous les éléments avant de permettre la vérification de l'élément. Ainsi, lorsque les utilisateurs cliquent sur une case, toutes les autres cases ne sont pas cochées.

Pour décocher tous les éléments cochés utiliser simplement:

private static void uncheckAll(CheckedListBox listBox) { 
     IEnumerator myEnumerator; 
     myEnumerator = listBox.CheckedIndices.GetEnumerator(); 
     int y; 
     while (myEnumerator.MoveNext() != false) { 
      y = (int)myEnumerator.Current; 
      listBox.SetItemChecked(y, false); 
     } 
    } 

Donc, en cas ItemCheck vous devez exécuter uncheckAll(yourListBox) d'abord, puis simplement laisser l'élément vérifier.

Edit: Je l'ai testé avec le code ci-dessous et il fonctionne. Sans le si il jette l'exception.

private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) { 
     if (e.NewValue == CheckState.Checked) { 
      IEnumerator myEnumerator; 
      myEnumerator = checkedListBox1.CheckedIndices.GetEnumerator(); 
      int y; 
      while (myEnumerator.MoveNext() != false) { 
       y = (int)myEnumerator.Current; 
       checkedListBox1.SetItemChecked(y, false); 
      } 
     } 

    } 
+0

Merci Madboy, cependant la méthode uncheckAll provoque le lancement d'une exception StackOverflowException - chaque fois que vous pouvez utiliser SetItemChecked, l'événement ItemChecked est déclenché, ce qui signifie que uncheckAll est également déclenché en permanence. A moins d'avoir oublié de faire quelque chose? – AndrewC

+0

Voir ma réponse mise à jour. – MadBoy

+0

excellent, fonctionne parfaitement. Je vous remercie! – AndrewC

1

propriété Essayez mis .SelectionMode = SelectionMode.One.

+0

Cela ne me permet de sélectionner qu'un seul élément à la fois (c'est-à-dire surligner), il ne contrôle pas le nombre d'éléments qui peuvent être vérifiés à tout moment. :) – AndrewC

0

J'ai dû faire quelque chose de similaire pour sélectionner un seul utilisateur parmi une liste massive. Il n'y a pas de RadioListBox à proprement parler, donc je l'ai juste codé manuellement ...

Désolé, c'est en VB, je l'ai juste collé, la logique est la même.

Private m_NoFire As Boolean = False 

Private Sub lstSource_ItemCheck(_ 
     ByVal sender As Object, _ 
     ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles lstSource.ItemCheck 

    'When the checked state is set programatically, 
    'this event will still fire and cause the loop 
    'to run - infinatly. This line prevents that. 
    If m_NoFire Then Exit Sub 
    m_NoFire = True 

    'Ensure only one item is selected 
    For i As Integer = 0 To lstSource.Items.Count - 1 
     If Not lstSource.SelectedIndex = i Then 
      lstSource.SetItemChecked(i, False) 
     End If 
    Next 

    m_NoFire = False 

End Sub '-- lstSource_ItemCheck 
+0

KMan vient de poster un bien meilleur moyen. Pourtant, ce code a été dans le projet depuis environ 5 ans et je ne le change pas maintenant: D – Tom

+0

@ KMan sur les réflexions, en regardant ce lien, je ne pense pas que cela limite la vérification, seule sélection. – Tom

0

Ce code pourrait être beaucoup plus simple, nécessite une variable. Chaque fois que vous cochez une nouvelle case, la dernière case sera décochée, ce qui entraînera l'absence de deux éléments cochés ou plus à ce moment-là. Assurez-vous que la propriété SelectionMode = SelectionMode.One; est définie comme indiqué.

private int lastCheck = -1; 
    private void CheckListBox_IndexChanged(object sender, EventArgs e) { 
     int toUncheck = lastCheck; 
     if (toUncheck != -1) 
      CheckListBox.SetItemChecked(toUncheck, false); 
     lastCheck = CheckListBox.SelectedIndex; 
     CheckListBox.SetItemChecked(lastCheck, true); 
    } 

Ou alternativly vous pouvez définir lastCheck la valeur par défaut cochée la case si nécessaire, faire par:

private void FormFoo_Load(object sender, EventArgs e) { 
     CheckListBox.SelectedIndex = 0; 
     lastCheck = CheckListBox.SelectedIndex; 
    } 

puis le reste du code que je l'ai mentionné ci-dessus est ci-dessous.

Avis *: J'ai utilisé lastCheck = **CheckListBox.SelectedIndex;** pour soutenir le déplacement du clavier, juste au cas où.