简体   繁体   中英

How to update datasource of datagridview from another thread in c#

I have a backgrounder thread running along with a ui thread. Now in the backgrounder_doWork method, i have a datatable that i am adding info to from a database. I want it to bind to a datagridview in the ui thread to display to the user. So when the dataTable is updated with new info as it comes in from the database, the datagridview should automatically refresh to add/subtract any new rows of info recieved from the backgrounding thread. How can i do this? I have tried this:

private delegate void dGValueDelegate();
private void dGVValue()
{
    BindingSource bSource = new BindingSource();
    dtFailures.DataSource = bSource;
    bSource.DataSource = dt;
}

where dt is a class level variable. Inside the backgrounder_dowork method, at the beginning i call the dGVVAlue method and then after that the info gets added to the datatable in the backgrounding thread. The datagridview wont display however...

The code below should work for you:

private delegate void SetDGVValueDelegate(BindingList<Something> items);

void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{    
    // Some call to your data access layer to get dt

    SetDGVValue(DataTable dt)
}

private void SetDGVValue(DataTable dt)
{    
    if (dataGridView1.InvokeRequired)    
    {        
        dataGridView1.Invoke(new SetDGVValueDelegate(SetDGVValue), dt);    
    }    
    else    
    {        
        dataGridView1.DataSource = dt;    
    }
}

In your question you mention using BindingSource, which does not have an Invoke method - if you have a binding source you can instead Invoke on the form:

// On the form
public void SetBindingSourceDataSource(object newDataSource)
{
    if (InvokeRequired)
        Invoke(new Action<object>(SetBindingSourceDataSource), newDataSource);
    else
        this.bindingSource.DataSource = newDataSource;
}

You can also do this in a single line using Lamda expressions:

void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{    
    // Some call to your data access layer to get dt

    dataGridView1.Invoke((Action)(() => dataGridView1.DataSource = dt));
}

此外,使用DataGridView.Invoke(Delegate)方法将允许您确保在其所属的线程中对datagridview进行更改。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM