使用sqldatareader逐行从另一个线程填充DataGridView

时间:2012-11-01 13:41:32

标签: c# sql-server

我正在尝试执行一些需要很长时间并返回大量行的SQL查询,这就是我使用SqlDataReader返回行的原因。

我在一个单独的线程中执行查询,因此在返回行时UI可用。

我还有一个数据表,我正在填充SqlDataReader,DataTable绑定到BindingSource,BindingSource绑定到DataGridView。

问题是DataGridView似乎无法将DataTable的列绑定到DataGridView中的列,并且网格中的所有单元格都显示为空白。即使AutoGenerateColumns = true,也不会显示数据!

下面是一个与我的问题非常相似的示例代码:

public partial class Form2 : Form
{
    BindingSource binding;
    DataTable dt = new DataTable();
    DataGridView dgv;

    public Form2()
    {
        InitializeComponent();

        binding = new BindingSource();
        binding.DataSource = dt;

        dgv = new DataGridView();
        dgv.Columns.Add("Column1", "Column1");
        dgv.Columns[0].DataPropertyName = "Column1";
        dgv.AutoGenerateColumns = false;
        dgv.DataSource = binding;
        dgv.Click += new EventHandler(dgv_Click);
        this.Controls.Add(dgv);

        dostuff();  // ON FIRST TRY 5 ROWS SHOWN
    }

    void dgv_Click(object sender, EventArgs e)
    {
        dostuff();  // ON SECOND RUN EVERYTHING IS CLEARED!
    }

    void dostuff()
    {            
        dgv.DataSource = null;
        dt.Rows.Clear();
        dt.Columns.Clear();
        dgv.DataSource = binding;

        BackgroundWorker bgw = new BackgroundWorker();
        bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
        bgw.RunWorkerAsync();

    }

    void bgw_DoWork(object sender, DoWorkEventArgs e)
    {
        dt.Rows.Clear();
        dt.Columns.Clear();

        dt.Columns.Add("Column1");

        for (int i = 0; i < 5; i++)
        {
            DataRow r = dt.NewRow();
            r[0] = i;
            dt.Rows.Add(r);
        }
    }
}

2 个答案:

答案 0 :(得分:2)

您需要刷新DataGridView方法末尾的bgw_DoWork,并且需要使用Invoke,因为必须在UI线程上运行Refresh方法。以下是修改后的bgw_DoWork方法:

void bgw_DoWork(object sender, DoWorkEventArgs e)
{
    dt.Rows.Clear();
    dt.Columns.Clear();

    dt.Columns.Add("Column1");

    for (int i = 0; i < 5; i++)
    {
        DataRow r = dt.NewRow();
        r[0] = i;
        dt.Rows.Add(r);
    }

    dgv.Invoke((MethodInvoker) delegate() { dgv.Refresh(); });
}

答案 1 :(得分:0)

您可以在DataGridView中创建列,并将每个DataGridViewColumn的{​​{1}}设置为DataPropertyName中相应列的名称。如下所示:http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcolumn.datapropertyname.aspx