1
votes

Les cases à cocher c # DataGridView ne seront pas cochées

J'ai un DataGridView simple qui utilise la table Orders (OrderID, CustomerID, ShipName) de base de données northwind . Après le chargement initial, j'ajoute une nouvelle colonne à chaque ligne avec une case à cocher dessus. Maintenant, mon interface utilisateur ressemble à ceci .

Code pour ajouter la colonne supplémentaire avec la case à cocher. p>

for (int i = dataGridView1.Rows.Count-1; i >=0 ; i--)
{
    DataGridViewRow row = dataGridView1.Rows[i];
    bool isChecked = dataGridView1[3, i].Value != null && (bool)dataGridView1[3, i].Value != false;
    if (isChecked)
    {
        dataGridView1.Rows.RemoveAt(i);
    }
}

De plus, j'ai un bouton appelé supprimer qui, en cas de clic, devrait supprimer toutes les lignes avec la case cochée.

DataGridViewCheckBoxColumn checkColumn = new DataGridViewCheckBoxColumn();
checkColumn.Name = "Delete";
checkColumn.HeaderText = "Delete";
checkColumn.Width = 50;
checkColumn.ReadOnly = false;
dataGridView1.Columns.Add(checkColumn);

Cependant, chaque fois que je clique sur des cases à cocher puis sur le bouton Supprimer, le dernier cliqué n'est toujours pas supprimé.

Après quelques débogages, j'ai trouvé que si je clique sur certaines cases, alors cliquez n'importe où ailleurs dans l'interface utilisateur, puis sur le bouton supprimer, cela fonctionne comme prévu.

Alors, est-ce un bogue connu? Est-ce que je fais quelque chose de mal?

MISE À JOUR

Ajout d'un compteur à la méthode de suppression pour que je puisse compter le nombre de cases à cocher et passer à un autre test:

1: J'ai cliqué sur les deux premières cases à cocher puis sur le bouton Supprimer. La première ligne a été supprimée, le compteur était 1.

2: J'ai cliqué sur les deux premières cases à cocher puis à l'extérieur sur un espace vide de l'interface utilisateur, puis sur le bouton Supprimer.Les deux lignes cochées ont été supprimées.Le compteur était 2.

Donc le problème est-ce que visuellement les cases à cocher sont cochées, mais dans le code, la dernière ne l'est pas à moins que je change de focus.


9 commentaires

vous pouvez écouter la case à cocher datagrid cliquez et ajoutez la ligne sélectionnée à une 'DeleteList'. En cliquant sur le bouton Supprimer , tous les éléments de la DeleteList peuvent être supprimés de la collection de grille de données d'origine.


J'ai pensé à cette solution de contournement, mais est-ce que je fais quelque chose de mal avec ma solution actuelle?


Vous pouvez utiliser (bool) dataGridView1 [3, i] .Value dans votre isChecked. Je ne sais pas si cela fera une différence, mais vérifier someBool! = False équivaut à someBool


J'ai mis à jour ma question avec plus d'informations


Peut-être que l'ajout d'un Update () ferait l'affaire, il suffit de définir un événement pour cellvaluged avec la méthode de mise à jour


Notez qu'il existe une grande différence entre la suppression d'une ligne et sa suppression.


Copie possible de Comment arrêter l'édition de DataGridView après avoir vérifié la cellule?


Je suppose qu'il se passe autre chose. Je «copie / colle» le code affiché et je ne peux PAS reproduire le problème que vous décrivez. Comme vous l'avez commenté… "chaque fois que je clique sur des cases à cocher puis sur le bouton Supprimer, le dernier sur lequel j'ai cliqué n'est toujours pas supprimé." … cela ne s'est pas produit dans mes tests variés, toutes les lignes étaient "toujours" correctement supprimé.


De plus, cliquer n'importe où ailleurs dans l'interface utilisateur, un autre bouton, une autre ligne… cliquer n'importe où ne faisait aucune différence, toutes les lignes étaient correctement supprimées lorsque le bouton de suppression était cliqué. Encore une fois, je suppose que quelque chose d'autre peut se passer. Comment les données sont-elles lues dans la grille?


3 Réponses :


0
votes
foreach (DataGridViewRow row in dataGridView1.Rows)
{
     if (Convert.ToBoolean(row.Cells[3].Value)) //Column Delete
     {
          // what you want to do
     }
}

  You've forgotten to convert the value to boolean by using Convert.ToBoolean()

1 commentaires

Même comportement exact. Le dernier que je vérifie n'est pas supprimé bien qu'il soit vérifié.



0
votes

Puis-je vous suggérer de modifier votre approche? Je pense que la boucle for peut ne pas fonctionner comme prévu

        List<int> indexesToDelete = new List<int>();
        dgv.Rows.Cast<DataGridViewRow>().ToList().ForEach(x =>
        {
            if (x.Cells[3].Value != null && (bool)x.Cells[3].Value != false)
            {
                indexesToDelete.Add(x.Index);
            };
        });
        indexesToDelete.Reverse();
        indexesToDelete.ForEach(i => dgv.Rows.RemoveAt(i));

si vous souhaitez continuer avec votre approche, je suggérerais au lieu d'utiliser removeAt, utilisez remove et donnez la ligne au lieu de l'index p >


1 commentaires

J'ai fait de nombreux tests sur ma boucle et c'est bien. J'ai mis à jour ma question avec plus d'informations.



0
votes

Que diriez-vous d'un gestionnaire d'événements lorsque vous cliquez sur une cellule, puis associez-le au nom / numéro de la colonne, puis supprimez l'index:

   private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        if (e.ColumnIndex == 3)
        {

/* any aditional verifications, can be added, then remove from the index selected */

            dataGridView1.Rows.RemoveAt(e.RowIndex);
        }
    }


0 commentaires