0

I am relativaly new to Visual C#. I am creating a program where there are a list of pictureboxes. I have a for loop, that plays a .wav file according to the image in the pictureboxes. I am using the PlaySync method, so that for every i in the loop, a .wav file is played (corresponding to a different picturebox) until the end, and then the i increases and then a different note is played.
For every note (basically every i of the loop) i want to change the background color of the picturebox that the .wav file is being played.
The code runs without coloring the pictureboxes, unless I add a messagebox in the loop. I am pretty sure that I need an inerrupter in the loop in order to give the program a chance to color the pictureboxes. I have tried using delay (Thread.Sleep()) in order to break the program, but it doesn't work. Do I need to interupt the loop? If yes, what will work? This is my code: *arrindex is an integer that represents the number of notes to play *pboxlist = the list of pictureboxes *tempind = the index of the list of pictureboxes

    for (int i = 0; i <= arrindex; i++)
            {               
                if (tempind < pboxlist.Count()) //coloring the pictureboxes
                {
                    if (tempind != -1)
                    {
                        pboxlist[tempind].BackColor = Color.Transparent; //coloring the previous picturebox back to transparent

                    }
                    tempind++;
                    pboxlist[tempind].BackColor = Color.LightPink;

                }


                    regwav[row, col].PlaySync(); // a matrix where the .wav files are stored (row and col are integers that determine which .wav file to play)


        }
Charles
  • 50,943
  • 13
  • 104
  • 142
XrockerX
  • 5
  • 4
  • In Windows Forms you can use Application.DoEvents to update UI, but it is better to move this code to worker thread. – Alex F Dec 24 '13 at 09:27
  • Pretty essential programming detail in GUI programming, your UI doesn't update until your program goes idle again. Don't use a for() loop, use a Timer instead. – Hans Passant Dec 24 '13 at 09:29

2 Answers2

0

You can use the Refresh() method to force the PictureBoxes to immediately refresh. It does not make your application responsive though, your form won't respond to any user interaction as long as the loop runs.

Another option is Application.DoEvents(), which makes the application respond to user interaction between every wave file, but it causes more trouble than you gain from it (you may end up running the same loop inside the first loop if you're not careful).

The last, but in most scenario's that take time, best method is using a separate thread from which the loop runs. The problem though is that properties of controls (like PictureBox.BackColor) can only be set in the thread the form was created in.

As Hans Passant mentioned in his comment, you can solve your problem by removing the loop altogether and using a timer, remembering the "current i value" yourself in ie. a form field.

See this link for an example of using a separate thread and invoking the form's thread.

C.Evenhuis
  • 25,996
  • 2
  • 58
  • 72
0

What probably happens is that you run PlaySync on the main thread, not allowing it to update the UI (i.e, change background colors).

Try to play it async instead

Shai
  • 25,159
  • 9
  • 44
  • 67