1

我正在编写一个处理数据库并将任何更改写入 ListView 以供用户处理它们的程序。之后,应该将所有更改写回 DB,但我不知道如何从 BGW 到达 ListView.ListViewItemCollection。我曾尝试使用 Control.Invoke,但我担心我还不够熟练,无法让它发挥作用。

我收到的错误说我无法从不是在其上创建的线程访问该控件

 private delegate void BGOUdate(ListView.ListViewItemCollection lvic);
 BGOU = new BGOUdate(ApplyChanges);
 bgw1.RunWorkerAsync(lvProducts.Items);

 private void bgwSearcher_DoWork(object sender, DoWorkEventArgs e)
    {          
        BGOU(e.Argument as ListView.ListViewItemCollection);                
    }

 private void ApplyChanges(ListView.ListViewItemCollection lvic)
    {
        ...
        foreach (ListViewItem item in lvic)
        {
            ...
        }
        ...
    }
4

1 回答 1

0

Control.Invoke是正确的步行方式。但是您需要将控制权传递给后台工作人员,而不仅仅是它ItemCollection

private void ApplyChanges(ListView lv) 
{ 
    lv.Invoke((Action)delegate
    {
        foreach (ListViewItem item in lv.Items) 
        { 
            ... 
        }
    }); 
    ... 
} 

这样,对 ListViewItems 的所有更改都将在创建控件的线程中进行。

Action是一个预定义的不带参数的 void 委托。关键字delegate将以下块标记为匿名函数并返回一个委托给 this,然后将其强制转换为Action可在控件上调用的一个。调用会Invoke导致传递的委托在与控件的窗口句柄关联的线程上执行,这几乎每次都是创建者线程。

也许,您应该考虑将 DataBinding 作为一种选项,以使 GUI 元素与您的数据保持同步。

于 2012-07-04T20:22:03.457 回答