0

I am trying to update an array of Labels which are on a form from a backgroundworker. Here is my code:

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();
    }
}

This does not work, but if I try to change text property of each label instead of the array, it works. How can I fix this? Also is there a shorter/better way of updating form controls from backgroundworkers than what I am doing for every single control on my form?

Edit: here is how I defined the array:

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

and here is the function that I call to assign the array:

    private void makeLabelArrays()
    {
        for (int i = 0; i < 6; i++)
        {
            arrLabel[i] = (Label)Groupbox1.Controls["label" + (i + 1).ToString()];
        }
    }
NESHOM
  • 899
  • 16
  • 46
  • Have you tried using a list instead of an array? – andypopa Jul 02 '14 at 04:32
  • In general Cross Thread happens if you update a form control in BThread you can declare a delegate and do this via invoke – saeed Jul 02 '14 at 04:35
  • Describe more on your scenario to check if you can achieve this in a Timer or not – saeed Jul 02 '14 at 04:37
  • @GrantWinney: I like your idea, but the array of values[i] are the values comming from hardware. Is is possible to update labels with these values using ProgressChanged? or it is just for updating the progress? – NESHOM Jul 02 '14 at 04:50
  • @GrantWinney: yes please post an example. thank you. – NESHOM Jul 02 '14 at 05:00

2 Answers2

1

try the following

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();
    }
}
X-Istence
  • 16,324
  • 6
  • 57
  • 74
Srikanth
  • 980
  • 3
  • 16
  • 30
  • thank you, but how can I do this in backgroundworker without defining the new function AssignText()? – NESHOM Jul 02 '14 at 04:52
1

I'm assuming what some of your code looks like; I may be wrong.

You can use the ReportProgress() method to send two pieces of information back to the UI thread - the percentage of completeness (doesn't really apply in your case so I specified 0) and some piece of data (any object you want, just a number in this case).

Then you can get the data in the ProgressChanged event and execute code that touches the 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();
}

Make sure you enable reporting progress, as it's disabled by default.

backgroundWorker1.WorkerReportsProgress = true;
Grant Winney
  • 65,241
  • 13
  • 115
  • 165
  • Thank you for your example, but it shows System.NullReferenceException for me. I am using array, but you used list. Do you think this is the issue? – NESHOM Jul 02 '14 at 05:21
  • I just edited the main question and included the code for defining the array. – NESHOM Jul 02 '14 at 05:31
  • It throws exception when I validate the array in ProgressChanged() event even with this simple validation **arrLabel[1].Text = "test";**. BTW. I tried List and it doesn't work either. – NESHOM Jul 02 '14 at 05:39
  • yes, you are right! then why is it null? it doesn't show any error in makeLabelArrays()! – NESHOM Jul 02 '14 at 05:47
  • Yes, I defined arrLabel at the beginning of the class (class-level) and I just use them in the makeLabelArrays() function just like the code I posted. Is this wrong? – NESHOM Jul 02 '14 at 05:54
  • I found the problem! Each label is on a separate GroupBox (a) and these GroupBoxes are all in another GroupBox (A). I am sorry for the mistake! Your code is working perfectly! Now, is there any way I find the controls based on the GroupBox A and not GroupBoxes a? – NESHOM Jul 02 '14 at 05:59