Déclenchement d'un événement de changement de valeur dans DataGridView
j'ai une vue de grille qui a une colonne de case à cocher, et je veux déclencher un événement de dessin dès que la valeur de la cellule est activée. J'ai essayé le ValueChaged et les CellEndEdit et BeginEdit, et j'ai choisi le mode de sélection comme CellSelect. Comme pour les 2 premiers événements, l'événement a été déclenché à la fin du mode édition, comme sortir de la cellule actuelle, ou aller-retour. C'est juste un comportement bizarre.
Est-il rien qui déclenche l'événement sur la grille vue dès que la valeur de la cellule est modifiée?
Cordialement,
14 réponses
un de mes collègues recommande de piéger L'événement en question. Voir http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged.aspx.
j'utilise L'événement CellContentClick, qui s'assure que l'Utilisateur a cliqué sur la case à cocher. Il ne feu plusieurs fois même si l'utilisateur reste dans la même cellule. Le seul problème est que la Valeur n'est pas mise à jour, et renvoie toujours "faux" pour décochée. L'astuce est d'utiliser l' .La propriété EditedFormattedValue de la cellule au lieu de la propriété Value. La valeur Editedformatteded va suivre avec le crochet et est ce que l'on souhaite que la valeur avait en elle lorsque le CellContentClick est licencié.
pas besoin de minuterie, pas besoin de truc de fantaisie, il suffit D'utiliser L'événement CellContentClick et d'inspecter la valeur Editedformatted pour dire dans quel état la case à cocher va / vient de tomber. Si EditedFormattedValue = true, la case est cochée.
une autre façon est de gérer L'événement CellContentClick (qui ne vous donne pas la valeur actuelle dans la propriété de valeur de la cellule), call grid.Commitédit (DataGridViewDataErrorContexts.Commit) pour mettre à jour la valeur qui à son tour va lancer CellValueChanged où vous pouvez ensuite obtenir la valeur actuelle (i.e. correct) DataGridViewCheckBoxColumn.
private void grid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
grid.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
private void grid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
// do something with grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value
}
cible. cadre de travail du réseau: 2.0
essayez de vous connecter à L'événement CellContentClick. Le DataGridViewCellEventArgs aura un ColumnIndex et un RowIndex pour que vous puissiez savoir si un ChecboxCell a été cliqué. La bonne chose à propos de cet événement est qu'il ne se déclenche que si la case à cocher elle-même a été cliquée. Si vous cliquez sur la zone blanche de la cellule autour de la case, il ne se déclenche pas. De cette façon, vous êtes à peu près garanti que la valeur de la case à cocher a été changée lorsque cet événement se déclenche. Vous pouvez alors appeler Invalidate () pour déclencher votre événement de dessin, ainsi qu'un appel à EndEdit() pour déclencher l'édition de la fin de la ligne si vous en avez besoin.
je l'ai enfin mise en œuvre de cette façon
private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
{
if (dataGridView1[e.ColumnIndex, e.RowIndex].GetContentBounds(e.RowIndex).Contains(e.Location))
{
cellEndEditTimer.Start();
}
}
}
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{ /*place your code here*/}
private void cellEndEditTimer_Tick(object sender, EventArgs e)
{
dataGridView1.EndEdit();
cellEndEditTimer.Stop();
}
j'avais le MÊME PROBLÈME, MAIS j'ai trouvé une solution différente:
si vous faites la colonne ou l'ensemble de la grille "lire seulement" de sorte que lorsque l'utilisateur clique sur la case, il ne change pas de valeur.
Heureusement, le DataGridView.CellClick
événement est déclenché.
Dans mon cas, je fais ce qui suit dans le cellClick
événement:
if (jM_jobTasksDataGridView.Columns[e.ColumnIndex].CellType.Name == "DataGridViewCheckBoxCell")
Mais vous pouvez vérifier le nom de la colonne si vous avez plus d'une colonne de cases à cocher.
je fais alors toute la modification / sauvegarde de la dataset moi-même.
Petite mise à jour.... Assurez-vous d'utiliser EditedFormattedValue
au lieu de value
comme j'ai essayé value
mais il ne donne jamais le statut de droit qui est vérifié / non vérifié la plupart du site utilisent encore value
mais comme utilisé dans le dernier C # 2010 express ci-dessous est un moyen d'accès..
grdJobDetails.Rows[e.RowIndex].Cells[0].EditedFormattedValue
_CellValueChanged
l'événement suggéré ou utilisé par quelques-uns doit être utilisable dans certains cas, mais si vous cherchez chaque contrôle/uncheck de cellule, assurez-vous d'utiliser _CellContentClick
sinon je ne vois pas à chaque fois _CellValueChanged
est déclenché.. qui est si la même case est cliqué dessus et plus encore, il ne s'allume pas _CellValueChanged
mais si vous cliquez alternativement par exemple, vous avez deux chekbox et cliquez sur l'un après l'autre _CellValueChanged
événement sera déclenché, mais généralement, si vous cherchez évènement qui se déclenche à chaque fois que la cellule est de cocher/décocher _CellValueChanged
n'est pas déclenché.
cellEndEditTimer.Démarrer();
cette ligne permet à datagridview de mettre à jour la liste des cases cochées
je vous Remercie.
l'événement" EditingControlShowing " ne démarre pas sur le changement de valeur de la case à cocher. Parce que le style d'affichage de la case à cocher ne change pas.
la solution que j'ai utilisée est la suivante. (J'ai utilisé CellContentClick événement)
private void gGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (string.Compare(gGridView1.CurrentCell.OwningColumn.Name, "CheckBoxColumn") == 0)
{
bool checkBoxStatus = Convert.ToBoolean(gGridView1.CurrentCell.EditedFormattedValue);
//checkBoxStatus gives you whether checkbox cell value of selected row for the
//"CheckBoxColumn" column value is checked or not.
if(checkBoxStatus)
{
//write your code
}
else
{
//write your code
}
}
}
Le dessus a fonctionné pour moi. Faites-moi savoir si vous avez besoin d'aide.
j'ai trouvé une solution simple.
il suffit de changer le focus de la cellule après avoir cliqué sur la cellule.
private void DGV_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == "Here checkbox column id or name") {
DGV.Item(e.ColumnIndex, e.RowIndex + 1).Selected = true;
//Here your code
}
}
n'oubliez pas de vérifier si la colonne de votre index (ckeckbox + 1) existe.
j'ai trouvé une combinaison des deux premières réponses m'a donné ce dont j'avais besoin. J'ai utilisé L'événement Changedecelldirtatystatechangé et j'ai inspecté la valeur Editedformatted.
private void dgv_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
DataGridView dgv = (DataGridView)sender;
DataGridViewCell cell = dgv.CurrentCell;
if (cell.RowIndex >= 0 && cell.ColumnIndex == 3) // My checkbox column
{
// If checkbox checked, copy value from col 1 to col 2
if (dgv.Rows[cell.RowIndex].Cells[cell.ColumnIndex].EditedFormattedValue != null && dgv.Rows[cell.RowIndex].Cells[cell.ColumnIndex].EditedFormattedValue.Equals(true))
{
dgv.Rows[cell.RowIndex].Cells[1].Value = dgv.Rows[cell.RowIndex].Cells[2].Value;
}
}
}
utilisez ce code, quand vous voulez utiliser le checkedChanged
événement dans DataGrid View:
private void grdBill_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
grdBill.CurrentCell = grdBill.Rows[grdBill.CurrentRow.Index].Cells["gBillNumber"];
}
private void grdBill_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
calcBill();
}
private void calcBill()
{
listBox1.Items.Clear();
for (int i = 0; i < grdBill.Rows.Count - 1; i++)
{
if (Convert.ToBoolean(grdBill.Rows[i].Cells["gCheck"].Value) == true)
{
listBox1.Items.Add(grdBill.Rows[i].Cells["gBillNumber"].Value.ToString());
}
}
}
Ici grdBill = DataGridView1, gCheck = CheckBox in GridView(First Column), gBillNumber = TextBox
dans la Grille (Deuxième colonne).
donc, quand nous voulons lancer un événement checkchanged pour chaque clic, d'abord faire le CellContentClick il va prendre feu quand l'Utilisateur a cliqué sur la zone de texte, puis il va déplacer la cellule actuelle à la colonne suivante, donc la colonne CellEndEdit va prendre feu, il va vérifier si la case à cocher est cochée et ajouter le "gBillNumber" dans la boîte de liste (en fonction calcBill).
travailler avec un contrôle non lié (c'est-à-dire gérer le contenu de manière programmée), sans L'EndEdit () il n'a appelé le CurrentCellDirtyStateChanged qu'une fois et puis jamais plus; mais j'ai constaté qu'avec L'EndEdit () CurrentCellDirtyStateChanged a été appelé deux fois (la seconde probablement causée par L'EndEdit () mais je n'ai pas vérifié), donc j'ai fait ce qui suit, qui a fonctionné le mieux pour moi:
bool myGridView_DoCheck = false;
private void myGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (!myGridView_DoCheck)
{
myGridView_DoCheck = true;
myGridView.EndEdit();
// do something here
}
else
myGridView_DoCheck = false;
}
chacun des CellClick
et CellMouseClick
réponses est fausse, parce que vous pouvez changer la valeur de la cellule avec le clavier et l'événement ne se déclenche pas. En outre, CurrentCellDirtyStateChanged
ne déclenche qu'une seule fois, ce qui signifie que si vous cochez/décochez la même case plusieurs fois, vous n'obtiendrez qu'un seul événement. En combinant quelques-unes des réponses ci-dessus, on obtient la solution simple suivante:
private void dgvList_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgvList.CurrentCell is DataGridViewCheckBoxCell)
dgvList.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
private void dgvList_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
// Now this will fire immediately when a check box cell is changed,
// regardless of whether the user uses the mouse, keyboard, or touchscreen.
//
// Value property is up to date, you DO NOT need EditedFormattedValue here.
}