2010-05-12 14 views
5

Tengo un DataGridView que está enlazado a un DataTable, que tiene una columna que es un doble y los valores que tenga que estar entre 0 y 1. Aquí está mi códigoDataGridView validar valor antiguo insted del nuevo valor

private void dgvImpRDP_InfinityRDPLogin_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) 
{ 
    if (e.ColumnIndex == dtxtPercentageOfUsersAllowed.Index) 
    { 
     double percentage; 
     if(dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value.GetType() == typeof(double)) 
      percentage = (double)dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value; 
     else if (!double.TryParse(dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value.ToString(), out percentage)) 
     { 
      e.Cancel = true; 
      dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1"; 
      return; 
     } 
     if (percentage < 0 || percentage > 1) 
     { 
      e.Cancel = true; 
      dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1"; 
     } 
    } 
} 

Sin embargo, mi problema cuando dgvImpRDP_InfinityRDPLogin_CellValidating dispara dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value contendrá el valor anterior antes de la edición, no el nuevo valor.

Por ejemplo digamos el valor anterior fue 0,1 y entro 3. El código anterior se ejecuta al salir de la celda y dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].Value será 0,1 para esa ejecución, el código es válido y escribe los datos a la DataTable.

Hago clic una segunda vez, trato de irme, y esta vez se comporta como debería, levanta el icono de error de la celda y me impide irme. Intento ingresar el valor correcto (digamos .7) pero el Value seguirá siendo 3 y ahora no hay forma de salir de la celda porque está bloqueado debido al error y mi código de validación nunca empujará el nuevo valor.

Cualquier recomendación sería muy apreciada.

EDIT - Nueva versión del código basado en la sugerencia de Stuart e imitando el estilo que usa el artículo de MSDN. Todavía se comporta igual.

private void dgvImpRDP_InfinityRDPLogin_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) 
{ 
    if (e.ColumnIndex == dtxtPercentageOfUsersAllowed.Index) 
    { 
     dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = String.Empty; 
     double percentage; 
     if (!double.TryParse(dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].FormattedValue.ToString(), out percentage) || percentage < 0 || percentage > 1) 
     { 
      e.Cancel = true; 
      dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1"; 
      return; 
     } 
    } 
} 

Respuesta

4

Es necesario utilizar la propiedad FormattedValue de la instancia DataGridViewCellValidatingEventArgs en lugar del valor de la celda, ya que el valor de la celda no se actualiza hasta que la validación ha tenido éxito:

El texto introducido por el usuario a través de la interfaz de usuario (UI) se convierte en el valor de propiedad FormattedValue . Este es el valor que puede validar antes de se analiza en el valor de propiedad Valor de la celda. (MSDN)

+0

No, 'dgvImpRDP_InfinityRDPLogin [e.ColumnIndex, e.RowIndex] .FormattedValue' =" 0.1" después de haber introducido 5 –

+1

Nop. ¡Tienes que mirar e.FormattedValue! – stuartd

+0

¡Ah! gracias, ni siquiera noté el valor formateado dentro de e. –

1

¿Qué tal si hacemos algo como esto? Esto supone que está utilizando cuadros de texto en su vista de cuadrícula de datos, por lo que si está utilizando algún otro control, simplemente cámbielo a eso. (Aunque no estoy seguro de por qué la respuesta de Stuart Dunkeld no funcionó, FormattedValue debería tener el nuevo valor).

void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) 
    { 
    if (e.ColumnIndex == 0) // dtxtPercentageOfUsersAllowed.Index 
    { 
     object should_be_new_value = e.FormattedValue; 
     double percentage; 
     if (dgvImpRDP_InfinityRDPLogin.EditingControl != null) 
     { 
      string text = dgvImpRDP_InfinityRDPLogin.EditingControl.Text; 
      if (!double.TryParse(text, out percentage)) 
      { 
       e.Cancel = true; 
       dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1"; 
       return; 
      } 
      if (percentage < 0 || percentage > 1) 
      { 
       e.Cancel = true; 
       dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = "The value must be between 0 and 1"; 
      } 
      else 
      { 
       dgvImpRDP_InfinityRDPLogin[e.ColumnIndex, e.RowIndex].ErrorText = null; 
      } 
     } 
    } 
    } 
+0

Eso funcionó. Gracias. –

+0

No hay problema. Lo cambié un poco para usar el texto y no verificar el tipo. Debería dar los mismos resultados solo un poco más limpios, pero avíseme si no funciona y revertiré la publicación. – SwDevMan81

+0

No funciona porque EditingControll puede ser nulo si está validando y no se están editando cuadros actualmente. –

Cuestiones relacionadas