Soul Reaver
Soul Reaver

Reputation: 2092

C# DataGridView is not updating with DataTable

i have a DataTable with some data and i bind it with my DataGridView with this code:

dataGridView1.DataSource = Measures.Table;

In separate thread i read data from connected device and insert that into my DataTable with this code:

DataRow row = table.NewRow();
row[ "Time" ] = dt;
foreach ( var kvp in measures )
    row[ kvp.Key ] = kvp.Value;
table.Rows.Add( row );

On my Form I am able to change it's main control with a button. Both controls are UserControl, of which one consists the dataGridView1 DataGridView. When I add a row to my DataTable, my DataGridView does not update, until I switch to the other control, and move back to the one with DGV.

I have read some solutions on stack, which basically tell me that i should use BindingSource, but this code:

BindingSource source = new BindingSource();
source.DataSource = Measures.Table;
dataGridView1.DataSource = source;

does not work as well.

I don't know why this happens, because I have also created a simple app with just DGV and DataTable updated with Timer.Tick event and it works there. Anyone knows any reason why this DGV is not updating itself? It updates itself only when forced to redraw (with switching controls or just form resize)

Upvotes: 2

Views: 13674

Answers (3)

Ramgy Borja
Ramgy Borja

Reputation: 2458

Don't forget this line

datatable.AcceptChanges();

Upvotes: 1

Soul Reaver
Soul Reaver

Reputation: 2092

Ok, so I've found the culprit ... (Me ;P). The reason, that it works in a small simple app and it doesn't in my main app is quite simple:

  1. main app actualizes DataTable (later called DT) in a BackgroundWorker, in which I am pooling the device for availability of new data. BackgroundWorker.DoWork event is running aside from UI thread, so if I am updating DT there, it fires all DT events in the same thread, so UI actually does not know of any change in DT.
  2. simple app based on Timer.Tick - Tick event is fired in UI thread, so Invoke is not required, and every event of changed DataTable is fired in UI thread, which lets DGV to react to any change.

in other words, to make it work, without DGV.Refresh() or DGV.Items.Refresh() I've had to update DataTable in UI thread, here's how I am doing this:

var form = System.Windows.Forms.Application.OpenForms[0];
...
form.BeginInvoke( (Action)( () => CODE_THAT_ADDS_ROW_TO_DATATABLE ) );

Upvotes: 0

DRapp
DRapp

Reputation: 48129

First, a data grid binds to a DataView of a data table, and handles internally to use the source.DefaultView.

After your records are added to the table, issue a refresh via the Items...

dataGridView1.Items.Refresh();

You should not have to rebind the source... just caution if you are doing the items.refresh from a different thread because the grid is UI based and not behind-the-scenes.

Upvotes: 1

Related Questions