La mejor forma de actualizar DataGridView cuando actualiza la fuente de datos base

¿Cuál es la mejor manera de actualizar un DataGridView cuando actualiza la fuente de datos base?

Estoy actualizando el origen de datos con frecuencia y quería mostrar el resultado al usuario a medida que sucede.

Tengo algo como esto hecho (y funciona), pero anular la DataGridView.DataSource no parece ser la correcta.

 List itemStates = new List(); dataGridView1.DataSource = itemStates; for (int i = 0; i < 10; i++) { itemStates.Add(new ItemState { Id = i.ToString() }); dataGridView1.DataSource = null; dataGridView1.DataSource = itemStates; System.Threading.Thread.Sleep(500); } 

Bueno, no hay nada mejor que eso. Oficialmente, deberías usar

 dataGridView1.DataSource = typeof(List); dataGridView1.DataSource = itemStates; 

Sigue siendo una solución de tipo “borrar / restablecer fuente”, pero aún no he encontrado nada que pueda actualizar de forma confiable la fuente de datos DGV.

Me encontré con esto yo mismo. Mi recomendación: si tiene la propiedad de la fuente de datos, no use una lista . Use una BindingList . BindingList tiene eventos que se activan cuando se agregan o cambian elementos, y DataGridView se actualizará automáticamente cuando se activen estos eventos.

La solución más limpia, más eficiente y más amigable con el paradigma en este caso es usar System.Windows.Forms.BindingSource como un proxy entre su lista de elementos (datasource) y su DataGridView :

 var itemStates = new List(); var bindingSource1 = new System.Windows.Forms.BindingSource { DataSource = itemStates }; dataGridView1.DataSource = bindingSource1; 

Luego, al agregar elementos, use el método Add() de BindingSource lugar del método Add() de su lista:

 for (var i = 0; i < 10; i++) { bindingSource1.Add(new ItemState { Id = i.ToString() }); System.Threading.Thread.Sleep(500); } 

De esta forma, puede agregar elementos a su lista y notificar a DataGridView acerca de esas adiciones con la misma línea de código. No es necesario restablecer el DataSource DataGridView cada vez que realiza un cambio en la lista.

También vale la pena mencionar que puede colocar un BindingSource en su formulario directamente en el Diseñador de Formularios de Visual Studio y adjuntarlo como fuente de datos a su DataGridView también, lo que le ahorra una línea de código en el ejemplo anterior donde lo estoy haciendo a mano.

Observablecollection : representa una recostackción dinámica de datos que proporciona notificaciones cuando los artículos se agregan, eliminan o cuando se actualiza toda la lista. Puede enumerar sobre cualquier colección que implemente la interfaz IEnumerable. Sin embargo, para configurar enlaces dynamics para que las inserciones o eliminaciones en la colección actualicen la interfaz de usuario automáticamente, la colección debe implementar la interfaz INotifyCollectionChanged. Esta interfaz expone el evento CollectionChanged, un evento que debe plantearse cada vez que cambia la colección subyacente.

 Observablecollection itemStates = new Observablecollection(); for (int i = 0; i < 10; i++) { itemStates.Add(new ItemState { Id = i.ToString() }); } dataGridView1.DataSource = itemStates; 

Esto es copia mi respuesta de ESTE lugar.

Solo es necesario rellenar la cuadrícula de datos de esta manera:

 this.XXXTableAdapter.Fill(this.DataSet.XXX); 

Si usa automaticlly connect from dataGridView, este código se crea automáticamente en Form_Load ()

Está configurando el origen de datos dentro del ciclo y durmiendo 500 después de cada adición. ¿Por qué no simplemente agregar a los estados del elemento y luego establecer su fuente de datos DESPUÉS de haber agregado todo? Si quieres que el hilo duerma después de eso, bien. El primer bloque de código aquí es tuyo, el segundo bloque que modifiqué.

 for (int i = 0; i < 10; i++) { itemStates.Add(new ItemState { Id = i.ToString() }); dataGridView1.DataSource = null; dataGridView1.DataSource = itemStates; System.Threading.Thread.Sleep(500); } 

Cambie su código de la siguiente manera: esto es mucho más rápido.

 for (int i = 0; i < 10; i++) { itemStates.Add(new ItemState { Id = i.ToString() }); } dataGridView1.DataSource = typeof(List); dataGridView1.DataSource = itemStates; System.Threading.Thread.Sleep(500); 

Prueba este código

 List itemStates = new List(); for (int i = 0; i < 10; i++) { itemStates.Add(new ItemState { Id = i.ToString() }); dataGridView1.DataSource = itemStates; dataGridView1.DataBind(); System.Threading.Thread.Sleep(500); }