C#:从后台线程访问 datagridview1

标签 c# datagridview multithreading

我正在尝试从后台工作线程访问主线程上的 ui 控件。我知道这是一个众所周知的问题,但我找不到任何关于如何访问 datagridview 的信息,特别是从后台线程。我知道制作列表框的代码是:

private delegate void AddListBoxItemDelegate(object item);

private void AddListBoxItem(object item)
{
    //Check to see if the control is on another thread
    if (this.listBox1.InvokeRequired)
        this.listBox1.Invoke(new AddListBoxItemDelegate(this.AddListBoxItem), item);
    else
        this.listBox1.Items.Add(item);
}

如何使 datagridview 控件工作?另外,上述方法仅适用于一个列表框(listBox1),有没有办法制作一种适用于主 ui 中所有列表框控件的方法?

谢谢

最佳答案

Invoke DataGridView 上的方法与 ListBox 的工作方式相同.

下面是一个示例,其中 DataGridView最初绑定(bind)到 BindingList<items>然后我们创建一个新列表并绑定(bind)到它。这应该等同于您获得 DataTable 的要求从您对 Oracle 的调用并将其设置为 DataSource .

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

void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    // Some call to your data access infrastructure that returns the list of itmes
    // or in your case a datatable goes here, in my code I just create it in memory.
    BindingList<Something> items = new BindingList<Something>();
    items.Add(new Something() { Name = "does" });
    items.Add(new Something() { Name = "this" });
    items.Add(new Something() { Name = "work?" });

    SetDGVValue(BindingList<Something> items)
}

private void SetDGVValue(BindingList<Something> items)
{
    if (dataGridView1.InvokeRequired)
    {
        dataGridView1.Invoke(new SetDGVValueDelegate(SetDGVValue), items);
    }
    else
    {
        dataGridView1.DataSource = items;
    }
}

在我成功使用 DataGridView 的测试代码中,将该数据源设置为在 DoWork 事件处理程序中生成的数据源。

您还可以使用 RunWorkerCompleted回调,因为它被编码到 UI 线程。示例如下:

backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);

void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    dataGridView1[0, 0].Value = "Will this work?";
}

至于问题的第二部分,有几种方法可以实现这一点。最明显的是在调用 BackGroundWork 时传入要处理的 ListBox,如下所示:

backgroundWorker1.RunWorkerAsync(this.listBox2);

然后您可以在 DoWork 事件处理程序中转换参数对象:

void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    ListBox l = e.Argument as ListBox;

    // And now l is whichever listbox you passed in 
    // be careful to call invoke on it though, since you still have thread issues!               
}

关于C#:从后台线程访问 datagridview1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6363259/

相关文章:

c# - 如何获取datagridview组合框的选定项的值

c# - 更改列标题的 datagridview rowheader 的颜色 C#

c++ - 通过引用传递与通过指针传递 : Boost threads and deadline timer

c# - 在 NHibernate 中停止延迟加载或跳过加载属性?无法通过 WCF 序列化代理

c# - TextBox 中不显示换行符

C# Linq OrderBy 过滤 null 或空值到最后

java - 同时发出多个 Volley 请求

ios - SceneKit - 线程 - 在哪个线程上做什么?

c# - 翻页的WPF动画创意

c# - 如何在新的 Web 应用程序的 Global.asax 中实现 User.Identity.Name