C# - 使用委托从另一个线程更新GUI datagridview

时间:2013-09-27 15:58:51

标签: c# multithreading datagridview delegates

我正在尝试使用委托更新数据网格视图,其中包含在不同类和线程中计算的一些数据。不幸的是,我遇到各种不同的错误,这取决于我尝试的方法。

我试图在表单线程中执行的代码如下所示:

public partial class AcquireForm : Form
//
// ...
//
    // update the grid with results
    public delegate void delUpdateResultsGrid(int Index, Dictionary<string, double> scoreCard);
    public void UpdateResultsGrid(int Index, Dictionary<string, double> scoreCard)
    {
        if (!this.InvokeRequired)
        {
            //
            // Some code to sort the data from scoreCard goes here
            //

            DataGridViewRow myRow = dataGridViewResults.Rows[Index];
            DataGridViewCell myCell = myRow.Cells[1];
            myCell.Value = 1; // placeholder - the updated value goes here
            }
        }
        else
        {
            this.BeginInvoke(new delUpdateResultsGrid(UpdateResultsGrid), new object[] { Index, scoreCard});
        }
    }

现在,我需要让这个方法从我的其他线程和类运行。我试过了:

public class myOtherClass
//
// ...
//

    private void myOtherClassMethod(int myIndex)
    {
        // ...
        AcquireForm.delUpdateResultsGrid updatedelegate = new AcquireForm.delUpdateResultsGrid(AcquireForm.UpdateResultsGrid);
        updatedelegate(myIndex, myScoreCard);
    }

不幸的是,这给出了“非静态字段,方法或属性AcquireForm.UpdateResultsGrid(int,System.Collections.Generic.Dictionary)”错误所需的“对象引用”。我似乎根本无法引用UpdateResultsGrid方法......

我注意到了

public class myOtherClass
//
// ...
//

    private void myOtherClassMethod(int myIndex)
    {
        // ...
        AcquireForm acquireForm = new AcquireForm();
        acquireForm.UpdateResultsGrid(myIndex,myScoreCard);
    }

在编译时不会抛出任何错误,但它会尝试创建一个新表单,这是我不想做的事情。我不想创建一个新的AcquireForm实例,我想引用预先存在的实例,如果可能的话。

我也试过将UpdateResultsGrid方法设为静态,但是这会引发一些问题,包括使用“this。(any)”。

我也尝试将大多数UpdateResultsGrid方法移动到myOtherClassMethod中,只在委托中留下AcquireForm类。同样,这不起作用,因为许多对UI对象的引用都会中断(范围内没有任何dataGridViews)。

我在这里开始没有想法了。不幸的是,我对C#很新(正如你可能会说的那样),我正在编辑别人的代码,而不是从头开始编写我自己的代码。如果有人能就这个问题提出一些建议,那就非常感激了。

1 个答案:

答案 0 :(得分:0)

确保您的对象相互通信:您的myOtherClass将需要了解AcquireForm对象 - 您不能只创建一个新对象(就像您一样)发现了)。您需要将AcquireForm 对象传递给myOtherClass 对象(例如myOtherObject.SetForm(myAcquireForm)),并在需要时引用它。

如果您遇到调用问题可能会有所帮助 - 我如何调用“下一步”按钮点击:

BeginInvoke(new Action(()=>button_next_Click(null,null)));

此外,听起来这可能不应该是单独的类,你应该使用BackgroundWorkder代替。