Как обновить источник данных datagridview из другого потока в c # - PullRequest
3 голосов
/ 17 июня 2011

У меня есть фоновый поток, работающий вместе с потоком пользовательского интерфейса.Теперь в методе backgrounder_doWork у меня есть таблица данных, к которой я добавляю информацию из базы данных.Я хочу, чтобы он привязывался к представлению данных в потоке пользовательского интерфейса для отображения пользователю.Поэтому, когда в dataTable обновляется новая информация по мере ее поступления из базы данных, представление данных должно автоматически обновляться, чтобы добавлять / вычитать любые новые строки информации, полученные из фонового потока.Как я могу это сделать?Я пробовал это:

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

, где dt - переменная уровня класса.Внутри метода backgrounder_dowork вначале я вызываю метод dGVVAlue, а затем после этого информация добавляется в таблицу данных в фоновом потоке.Однако datagridview не будет отображаться ...

Ответы [ 2 ]

10 голосов
/ 18 июня 2011

Код ниже должен работать для вас:

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;    
    }
}

В своем вопросе вы упомянули об использовании BindingSource, у которого нет метода Invoke - если у вас есть источник привязки, вы можете вместо этого использовать Invoke в форме:

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

Вы также можете сделать это в одной строке, используя выражения Lamda:

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

    dataGridView1.Invoke((Action)(() => dataGridView1.DataSource = dt));
}
3 голосов
/ 17 июня 2011

Кроме того, использование метода DataGridView.Invoke (Delegate) позволит вам убедиться, что вы вносите изменения в свое представление данных в потоке, которому он принадлежит.

...