2009-05-30 22 views
7

Tengo una vista de cuadro de datos que llamaremos dataGridViewExample.Datagridview causando IndexOutOfRangeException al hacer clic en

Mi objeto (los tipos de datos no comunes se debe a mi base de datos SQLite es):

class MyObject 
{ 
    public Int64 Vnr { get; set; } 
    public string Name { get; set; } 
    public Single Price { get; set; } 
    public int Amount { get; set; } 
} 

Este es el código correspondiente:

//This form gets called with a .ShowDialog(); in my form1. 

private List<MyObjecte> ExampleList = new List<MyObject>(); 

public MyForm() 
{ 
    dataGridViewExample.DataSource = OrdreInkøbsListe; 
} 


private void AddtoDataGridViewExample() 
{ 
    //Add a new MyObject to the list 
    ExampleList.Add(new myObject() 
       { 
        Vnr = newVnr, 
        Amount = newAmount, 
        Price = newPrice, 
        Name = newName 
       }); 

    //refresh datasource 
    dataGridViewExample.DataSource = null; 
    dataGridViewExample.Refresh(); 
    dataGridViewExample.DataSource = OrdreInkøbsListe; 
    ddataGridViewExample.Refresh(); 
} 

Cuando se llama a MiFormulario con un .ShowDialog, se muestra bien y muestra mi ejemplo DataGridView muy bien. Como puede leer desde el código, el ExampleList está inicialmente vacío, por lo que solo muestra una vista de cuadrícula de datos vacía con 4 columnas: Vnr, Nombre, Precio & Cantidad. Si hago clic dentro, etc. no pasa nada, así que todo está funcionando como estaba previsto, hasta ahora.

Cada vez que llamo a AddtoDataGridViewExample() agrega el nuevo objeto a Datagridview, y datagridview se actualiza, enumerando todos los objetos agregados hasta el momento (se muestran como filas, de nuevo según el plan).

Ahora, recuerdo que acabo de decir que no pasó nada si ha hecho clic en el interior DataGridViewExample antes de que yo he llamado AddtoDataGridViewExample()? Bueno, después de haber llamado al AddtoDataGridViewExample() una o más veces, el programa se bloqueará si hago clic dentro de DataGridViewExample (por ejemplo: los usuarios quieren seleccionar una fila). Lanza una IndexOutOfRangeException y habla de un índice -1. También arroja la excepción en la otra forma, en la línea donde llamo MyForm con .ShowDialog();

Realmente estoy atascado en esto, ¿ustedes tienen alguna idea de lo que está mal? Mi única pista es que sí creo que la causa del problema puede ser la actualización del origen de datos DataGridViewExample. Otro importante nota: Todavía he vinculado cualquier evento a mi DataGridViewExample. Entonces puedes descartar esa idea.

Aquí es propiedades de todos los DataGridViewExample 's:

this.dataGridViewExample.AllowUserToAddRows = false; 
this.dataGridViewExample.AllowUserToDeleteRows = false; 
this.dataGridViewExample.AllowUserToResizeColumns = false; 
this.dataGridViewExample.AllowUserToResizeRows = false; 
this.dataGridViewExample.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill; 
this.dataGridViewExample.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 
this.dataGridViewExample.Location = new System.Drawing.Point(591, 53); 
this.dataGridViewExample.MultiSelect = false; 
this.dataGridViewExample.Name = "dataGridViewExample"; 
this.dataGridViewExample.ReadOnly = true; 
this.dataGridViewExample.RowHeadersVisible = false; 
this.dataGridViewExample.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 
this.dataGridViewExample.ShowEditingIcon = false; 
this.dataGridViewExample.Size = new System.Drawing.Size(240, 150); 
this.dataGridViewExample.TabIndex = 31; 
+1

¿Dónde está el código que controla el evento clic? Normalmente, esta excepción se produce porque está manejando un evento de clic y luego tratando de obtener la fila seleccionada cuando no hay una fila seleccionada. Tener una fila seleccionada y hacer clic en la cuadrícula son mutuamente excluyentes. Entonces, ¿dónde está el código que maneja el evento click que arroja la excepción? – Josh

+0

Aún he agregado cualquier evento a dataGridViewExample, esa es la parte alarmante :(así que, en todo caso, es un evento inbuildt el que está causando esto. – CasperT

Respuesta

17

supongo que el evento click intenta la fila seleccionada en ese momento y hacer algo con él, mientras que dataGridViewExample.DataSource = null; borra el origen de datos, y la fila seleccionada en ese momento llega a ser nulo .

Si configura DataGridView.DataSource en la lista, no necesita restablecerlo a nulo, actualizar y restablecerlo a la lista nuevamente (y actualizar de nuevo) para ver los cambios. Bastará con actualizar el DataGridView.

también puede simplemente tratar de usar un objeto BindingList<T> en lugar de un List<T>, el cual notificará automáticamente su rejilla de sus cambios internos (Añadir y eliminar elementos), y también hay una interfaz INotifyPropertyChanged se puede implementar en su clase MyObject, que hará que cada propiedad cambie en un objeto se muestre en la cuadrícula (para cualquier cambio realizado en el objeto en el código, y no a través de la cuadrícula).

+0

Esto suena muy interesante. ¿Podría mostrar algunos ejemplos de código? Especialmente cómo usar el enlace lista y cómo debo llamar a la actualización en mi método – CasperT

+0

Cambié la lista a bindinglist, eliminé todos los códigos de actualización y agregué una única actualización. Todo parece funcionar perfectamente, ¡Muchas gracias! Una solicitud rápida: ¿podría mostrar un ejemplo de código de cómo eliminar un determinado objeto de la BindingList? – CasperT

+0

No importa, imaginado todo. Gracias de nuevo – CasperT

0

¿Ha intentado ejecutar el depurador y romper cuando se lanza InedxOutOfRangeException para ver dónde se produce la excepción?

Seleccione Depurar> Excepciones luego hay un botón Buscar en el cuadro de diálogo para que no tenga que navegar a través de todas las posibilidades.

+1

Por alguna razón, eso no funciona. Los he revisado a todos y cuando esto me sucedió, el estudio visual estalló en la línea donde llamé a ShowDialog en el formulario que contenía. –

0

Tuve una situación similar. Asigné una lista genérica de cierto objeto a DataGridView. Luego, establecí el valor nulo en DataSource y después de eso, actualicé. Después de eso, asigno una lista de objetos a DataSource. Al hacer clic en la cuadrícula, se produjo un error de tiempo de ejecución IndexOutOfRange. Mi solución fue asignar una nueva lista vacía de mi objeto a esa grilla y actualizar, y luego de los cambios en mi lista de trabajo, los asigno a DataSource y llamo a Refresh. Ahora, funciona sin ningún bloqueo. Por favor busque en mi código antes:

grid.DataSource = null; 
grid.Refresh(); 
if(cases.Count() > 0) 
{ 
    grid.DataSource = cases; 
    grid.Refresh(); 
}    

Y ahora en mi código después:

grid.DataSource = new List<MyCase>(); 
grid.Refresh(); 
//do something with cases 
if(cases.Count() > 0) 
{ 
    grid.DataSource = cases; 
    grid.Refresh(); 
}