Home > Enterprise >  looping through an array one element at a time
looping through an array one element at a time

Time:10-01

When I do this for loop on a windows form app and I click a button to start this for loop, the label just changes to the last item in the array, how do I get it to go through the array one at a time?

for (int i = 0; i < WordsnQuestions.questions.Length; i  )
{
    lblScrambled.Text = WordsnQuestions.questions [i  ];
}

CodePudding user response:

The loop is too fast... the label changes for every item in the loop (note: loop, not array, because of another issue), but the form doesn't have a chance to repaint the form until after the loop is already finished. By this time we're already up to the last item, so that's what we see.

The typical fix for this is move the index outside of the method, and only show one item for each event:

int currentPosition = 0;
public void btnNext_Click(object sender, EventArgs e)
{
    lblScrambled.Text = WordsnQuestions.questions [currentPosition  ];
    if (currentPosition >= WordsnQuestions.questions.Length) currentPosition = 0;
}

Separate from this, the original code incremented the counter twice per loop iteration... but again, properly designing the interaction avoids this in the first place.

But let's say you wanted an animation effect. Then you might try something like this to slow things down (note only one increment operator is used):

for (int i = 0; i < WordsnQuestions.questions.Length; i  )
{
    lblScrambled.Text = WordsnQuestions.questions [i];
    Thread.Sleep(1000);
}

But this still won't work, because the code still does not yield control back to the form so it can repaint the window.

Now you might be tempted to do something like this:

for (int i = 0; i < WordsnQuestions.questions.Length; i  )
{
    lblScrambled.Text = WordsnQuestions.questions [i];
    Application.DoEvents();
    Thread.Sleep(1000);
}

This will seem to (finally!) work, because it does allow an event loop to finally process each of WM_PAINT messages. However, there are still all kinds of problems with it. Again, the correct solution is really to think more carefully about how the interaction should work in the first place.

CodePudding user response:

There are two issues here:

  1. i is twice so your skipping items #2, 4, 6... and looping over 1, 3, 5 ... etc
  2. lblScrambled.Text will have the last item and program will not fail if you have odd number of items.

Here is the updated code for you to try:

for (int i = 0; i < WordsnQuestions.questions.Length; i  )
{
    lblScrambled.Text  = WordsnQuestions.questions [i];
}
  • Related