Acerca de:

Este blog contiene los códigos, ejemplos y bases de datos que he usado cuando aprendía acerca de algún tema específico. En lugar de borrarlos (una vez dominado ya el tema), he decidido publicarlos :)

martes, 15 de enero de 2013

El Control DataGridView lanza una System.ArgumentOutOfRangeException al recorrer sus filas

Tengo un DataGridView llamado dGridVIew al cual le añado datos de la siguiente manera:

DataRow[] dRow = MetodoQueDevuelveUnArrayDeDataRows();
object[] param = new object[3];

for (int i = 0; i < dRow.Count(); i++)
      {
           param[0] = dRow[i]["Campo 1"];
           param[1] = dRow[i]["Campo 2"];
           param[2] = dRow[i]["Campo 3"];

// Evito una excepción al hacer click en las cabeceras y si alguna celda tiene valor nulo
       for (int j = 0; j < param.Length; j++)
             if (param[j] == DBNull.Value)
                 param[j] = String.Empty;

             d
GridView.Rows.Add(param);
      }

Todo bien hasta aquí. Pero sucedía que después de llamar a este código, en el control dGridView no se mostraban todas las filas añadidas, a menos que redimensionada el formulario contenedor. Peor aún, al recorrer las filas con las teclas de las flechas hacia arriba o abajo, me saltaba la siguiente excepción:

No se controló System.ArgumentOutOfRangeException
  Message=El valor de '484' no es válido para 'Value'. 'Value' debería estar entre 'minimum' y 'maximum'.
Nombre del parámetro: Value
  Source=System.Windows.Forms
  ParamName=Value
  StackTrace:
       en System.Windows.Forms.ScrollBar.set_Value(Int32 value)
       en System.Windows.Forms.DataGridView.ScrollRows(Int32 rowCount, Int32 deltaY, ScrollEventType scrollEventType)


Rebuscando en Internet, este blog me dio la solución.
Y era muy simple: Después de llenar el DataGridView se debe llamar al método PerformLayout de la siguiente manera:

dGridView.PerformLayout();

No he podido encontrar porqué esta función evita la excepción, ni siquiera en la web de Microsoft.

Update!!

El código de ejemplo aún tiene un error: el DataGridView dGridView aún puede tirar una excepción si hacemos clic a la cabecera de una columna que espera recibir datos numéricos. El código corregido es:

DataRow[] dRow = MetodoQueDevuelveUnArrayDeDataRows();
object[] param = new object[3];

// Los valores del sgte array deben coincidir con los nombres de las columnas
string[] columnas = { "Campo 1", "Campo 2", "Campo 3" };

for (int i = 0; i < dRow.Count(); i++)
      {
           param[0] = dRow[i]["Campo 1"];
           param[1] = dRow[i]["Campo 2"];
           param[2] = dRow[i]["Campo 3"];

       // Evito una excepción al hacer click en las cabeceras y si alguna celda tiene valor nulo
       for (int j = 0; j < param.Length; j++)
             if (param[j] == DBNull.Value)

             {
       // en el caso de trabajar directamente con un Datatable la sgte línea se reemplaza por: 
      //    if (unDataTable.Columns[columnas[j]].DataType == typeof(string))
                 if (dRow[i].Table.Columns[columnas[j]].DataType == typeof(string))
                      param[j] =
String.Empty;
                 else
                      param[j] = 0;
              }


             d
GridView.Rows.Add(param);
      }

dGridView.PerformLayout();

10 comentarios:

Anónimo dijo...

Muchas gracias me ha funcionado a la perfeccion

Anónimo dijo...

excelente! gracias.

Anónimo dijo...

Excelente, funciona

Anónimo dijo...

Excelente solución. Después de algunas horas de frustración...., lo bueno es que se arregló el problema. Gracias!!!!

Anónimo dijo...

Muchas gracias, si funciona.

Anónimo dijo...

gracias, resolvio mi problema que al cargar el dgv me lanzaba un error si enfocaba los últimos registros.

quisas sea por que lo modificas pero en ningun momento se actualiza, algo similar con las listas y el evento notifidatachanged en android.

Anónimo dijo...

Excelente solucion hermano!! me ayudo a mi problema!! Saludos

Zhylz dijo...

Estuve buceando en varios foros, probé esta solución y me fue de maravilla, gracias.

Anónimo dijo...

Es un error muy raro, la verdad no se porque ocurre pero la solución que das es super efectiva.

Muchas gracias

diego fernando colorado beltran dijo...

Muchas gracias por aporte, funcionó de maravilla