【问题标题】:Updating array of labels from backgroundworkers从后台工作人员更新标签数组
【发布时间】:2014-07-02 13:30:36
【问题描述】:

我正在尝试更新后台工作人员表单上的一组标签。这是我的代码:

for (int i = 0; i < 6; i++)
{
    if (this.InvokeRequired)
    {
        this.Invoke((MethodInvoker)delegate
        {
            arrLabel[i].Text = values[i].ToString();
        });
    }
    else
    {
        arrLabel[i].Text = values[i].ToString();
    }
}

这不起作用,但如果我尝试更改每个标签的文本属性而不是数组,它会起作用。我怎样才能解决这个问题?还有比我为表单上的每个控件所做的更新来自后台工作人员的表单控件的更短/更好的方法吗?

编辑:这是我定义数组的方式:

  private Label[] arrLabel = new Label[6];

这是我调用来分配数组的函数:

    private void makeLabelArrays()
    {
        for (int i = 0; i < 6; i++)
        {
            arrLabel[i] = (Label)Groupbox1.Controls["label" + (i + 1).ToString()];
        }
    }

【问题讨论】:

  • 你试过用列表代替数组吗?
  • 一般来说,如果您在 BThread 中更新表单控件,则会发生跨线程,您可以声明一个委托并通过调用来执行此操作
  • 描述更多关于你的场景以检查你是否可以在计时器中实现这一点
  • @GrantWinney:我喜欢你的想法,但是 values[i] 数组是来自硬件的值。是否可以使用 ProgressChanged 使用这些值更新标签?还是只是为了更新进度?
  • @GrantWinney:是的,请发布一个示例。谢谢。

标签: c# backgroundworker invokerequired


【解决方案1】:

我假设您的某些代码是什么样的;我可能错了。

您可以使用ReportProgress() 方法将两条信息发送回 UI 线程 - 完整性百分比(在您的情况下并不真正适用,因此我指定了 0)和一些数据(您的任何对象)想要,在这种情况下只是一个数字)。

然后你就可以在ProgressChanged事件中获取数据并执行触及UI的代码了。

private List<Label> arrLabel = new List<Label>();
private List<string> values = new List<string>(); 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    var bw = (BackgroundWorker)sender;

    for (int i = 0; i < 6; i++)
        bw.ReportProgress(0, i);
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    var currentIndex = Convert.ToInt32(e.UserState);

    arrLabel[currentIndex].Text = values[0].ToString();
}

确保您启用报告进度,因为它默认处于禁用状态。

backgroundWorker1.WorkerReportsProgress = true;

【讨论】:

  • 感谢您的示例,但它为我显示 System.NullReferenceException。我使用的是数组,但你使用的是列表。您认为这是问题所在吗?
  • 我刚刚编辑了主要问题并包含了定义数组的代码。
  • 当我在 ProgressChanged() 事件中验证数组时,即使使用这个简单的验证 arrLabel[1].Text = "test";,它也会引发异常。顺便提一句。我试过 List 也不行。
  • 是的,你是对的!那为什么它是空的?它在 makeLabelArrays() 中没有显示任何错误!
  • 是的,我在类(类级别)的开头定义了 arrLabel,我只是在 makeLabelArrays() 函数中使用它们,就像我发布的代码一样。这是错的吗?
【解决方案2】:

试试下面的

private delegate void delegateAssignText();

public void AssignText()
{
    if (this.InvokeRequired)
    {
        Invoke(new delegateAssignText(AssignText));
        return;
    }


    for (int i = 0; i < 6; i++)
    {
        arrLabel[i].Text = values[0].ToString();
    }
}

【讨论】:

  • 谢谢,但是如果不定义新函数AssignText(),如何在backgroundworker 中执行此操作?
猜你喜欢
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
  • 2013-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多