c# - evento - datagridviewcheckboxcolumn click event
Disparar un valor de casilla de verificación cambió el evento en DataGridView (14)
Al trabajar con un control independiente (es decir, administro el contenido mediante programación), sin EndEdit () solo se llama CurrentCellDirtyStateChanged una vez y luego nunca más; pero encontré que con el EndEdit () se llamó dos veces a CurrentCellDirtyStateChanged (el segundo probablemente causado por el EndEdit () pero no lo verifiqué), así que hice lo siguiente, que funcionó mejor para mí:
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;
}
Tengo una vista de cuadrícula que tiene una columna de casilla de verificación, y deseo activar un evento de dibujo tan pronto como se alterne el valor de la celda. Probé el ValueChaged y el CellEndEdit y BeginEdit, y elegí el modo de selección como CellSelect. En cuanto a los primeros 2 eventos, el evento se activó al finalizar el modo de edición, como salir de la celda actual o ir y venir. Es solo un comportamiento extraño.
¿Hay algo que active el evento en la vista de la cuadrícula tan pronto como se cambie el valor de la celda?
Atentamente,
Cada una de las respuestas de CellClick
y CellMouseClick
es incorrecta, porque puede cambiar el valor de la celda con el teclado y el evento no se activará. Además, CurrentCellDirtyStateChanged
solo se activa una vez, lo que significa que si marcas o desmarcas la misma casilla varias veces, solo obtendrás un evento. Combinando algunas de las respuestas anteriores se obtiene la siguiente solución simple:
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.
}
El evento "EditingControlShowing" no se activa al cambiar el valor de la casilla de verificación. Porque el estilo de visualización de la casilla de verificación no cambia.
La solución alternativa que he utilizado es la siguiente. (He utilizado el evento CellContentClick)
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
}
}
}
Lo anterior funcionó para mí. Por favor, hágamelo saber si necesita más ayuda.
Encontré una combinación de las dos primeras respuestas que me dieron lo que necesitaba. Usé el evento CurrentCellDirtyStateChanged e inspeccioné EditedFormattedValue.
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;
}
}
}
Encontré una solución simple.
Simplemente cambie el foco de la celda luego de hacer clic en la celda.
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
}
}
No olvide verificar si la columna de su índice (ckeckbox + 1) existe.
Finalmente lo implementé de esta manera
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();
}
Intenta conectarte al evento CellContentClick. DataGridViewCellEventArgs tendrá un ColumnIndex y un RowIndex para que pueda saber si se hizo clic en ChecboxCell. Lo bueno de este evento es que solo se activará si se hizo clic en la casilla de verificación real. Si hace clic en el área blanca de la celda alrededor de la casilla de verificación, no se disparará. De esta forma, está prácticamente garantizado que el valor de la casilla de verificación cambió cuando se desencadena este evento. A continuación, puede invocar Invalidate () para desencadenar su evento de dibujo, así como una llamada a EndEdit () para activar el final de la edición de la fila si así lo necesita.
Otra forma es manejar el evento CellContentClick (que no le proporciona el valor actual en la propiedad Value de la celda), llamar a grid.CommitEdit (DataGridViewDataErrorContexts.Commit) para actualizar el valor que a su vez activará CellValueChanged, donde podrá obtener el valor real (es decir, correcto) 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
}
Target .NET framework: 2.0
Pequeña actualización ... Asegúrate de usar EditedFormattedValue
lugar de value
ya que probé value
pero nunca da el estado correcto que está marcado / desactivado. La mayoría del sitio aún usa value
pero como se usa en la última versión de c. 2010 express es una forma de acceder ..
grdJobDetails.Rows[e.RowIndex].Cells[0].EditedFormattedValue
También el evento _CellValueChanged
sugerido o usado por pocos debe ser utilizable para algunos casos, pero si está buscando cada check / uncheck of cell asegúrese de usar _CellContentClick
else según mi aviso, no veo cada vez que se _CellValueChanged
... es decir, si el mismo casilla de verificación se hace clic una y otra vez no se dispara _CellValueChanged
pero si hace clic alternativamente, por ejemplo, tiene dos chekbox y haga clic en uno después de otro _CellValueChanged
evento se disparará, pero por lo general si busca evento para disparar cada vez que cualquier casilla es check / uncheck _CellValueChanged
no está despedido
Tuve el mismo problema, pero se me ocurrió una solución diferente:
Si convierte la columna o toda la cuadrícula en "Solo lectura" para que cuando el usuario haga clic en la casilla no cambie el valor.
Afortunadamente, el evento DataGridView.CellClick
todavía está activado. En mi caso, hago lo siguiente en el evento cellClick
:
if (jM_jobTasksDataGridView.Columns[e.ColumnIndex].CellType.Name == "DataGridViewCheckBoxCell")
Pero puede verificar el nombre de la columna si tiene más de una columna de casilla de verificación.
Luego hago toda la modificación / guardado del conjunto de datos.
Un colega mío recomienda atrapar el evento CurrentCellDirtyStateChanged. Consulte http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged.aspx .
Use este código cuando desee usar el evento checkedChanged
en 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());
}
}
}
Aquí, grdBill = DataGridView1, gCheck = CheckBox in GridView(First Column), gBillNumber = TextBox
en cuadrícula (segunda columna).
Por lo tanto, cuando deseamos activar el evento changechanged para cada clic, primero haga CellContentClick, se activará cuando el usuario haga clic en el cuadro de texto, luego moverá la celda actual a la siguiente columna, por lo que la columna CellEndEdit recibirá un aviso. si la casilla de verificación está marcada y agregue el "gBillNumber" en el cuadro de lista (en la función calcBill).
Uso el evento CellContentClick, que se asegura de que el usuario haga clic en la casilla de verificación. SÍ dispara varias veces incluso si el usuario permanece en la misma celda. El único problema es que el valor no se actualiza, y siempre devuelve "falso" para desmarcado. El truco es usar la propiedad .EditedFormattedValue de la celda en lugar de la propiedad Value. EditedFormattedValue hará un seguimiento con la marca de verificación y es lo que uno desea que tenga el valor cuando se active el CellContentClick.
No hay necesidad de un temporizador, no hay necesidad de cosas sofisticadas, solo use el evento CellContentClick e inspeccione el EditedFormattedValue para indicar en qué estado va la entrada / recién ingresada. Si EditedFormattedValue = true, se marca la casilla de verificación.
cellEndEditTimer.Start ();
esta línea hace que datagridview actualice la lista de casillas marcadas
Gracias.