0

I have an if statement, inside that if statement is a foreach, for accessing each string from a string[].

The strings are some parameters for an NPC which are read from a file. The first one represents the NPC type which are two : "battle" and "teach", the last string[] for a "teach" NPC is "end", and the rest of parameters represents photo names, which I want to load in a "dialog" PictureBox.

My test file looks like this:

teach
poza1
poza2
end

So I have 2 photos to load in the dialog PictureBox. The idea is that I must pause for 5 seconds that foreach statement, otherwise the dialog PictureBox pictures will be loaded too fast, and I won't see them.

So I tried to do that, and here is how the code looks:

if (date[0].Equals("teach")) //the first line of the date[] string, date represent the text from the file
{
    foreach (string parametru in date) // i think that you know what this does
    {
        if (parametru != "teach" && parametru != "end") // checking if the parameter isn't the first or the last line of the file
        {

            dialog.ImageLocation = folder + "/npc/" + score_npc + "/" + parametru + ".png"; //loading the photo
            System.Threading.Thread.Sleep(5000);

        }
    }
    //other instructions , irelevants in my opinion
}

In my attempt of debugging this, I realised that if I use a MessageBox, the function will load the both photos. Also I'm sure of the fact that the parameters will pass the if statement.

It seems so easy to fix this error, but I can't figure out how to do it.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
Papanash
  • 59
  • 7
  • Before you call Sleep, call `Application.DoEvents()`, although this is frowned upon and isn't typically the right thing to do. Technically you want to do a `dialog.Invoke` and in the delegate procedure set the image. – Ron Beyer May 13 '15 at 20:20
  • @DanielA.White yes this is in winforms – Papanash May 13 '15 at 20:28
  • You are loading the images before the pb has time to show them. if you want to use some kind of animation a Timer would be better, but if you call PB.Refresh before the thread.Sleep it should work as well.. – TaW May 13 '15 at 20:29
  • @RonBeyer how can i set the image in the delegate procedure – Papanash May 13 '15 at 20:29
  • Something like `dialog.Invoke(delegate { dialog.ImageLocation = ...; });` – Ron Beyer May 13 '15 at 20:31

2 Answers2

0

You probably need to issue a PictureBox.Refresh and/or a DoEvents command for the picture box to actually get a chance to load and display the picture.

The MessageBox automatically performs a DoEvents ... which is why it is working during debugging.

Marc Johnston
  • 1,276
  • 1
  • 7
  • 16
0

What you're doing now just freezes the UI. Use a System.Windows.Forms.Timer instead. Drop a Timer from the toolbox onto your Form.

Then create some fields that the Timer can access, to store your pics and the current pic position:

private List<string> pics = new List<string>();
private int currentPic = 0;

Finally, load it up with the pics you want to display, and start the Timer to go through them:

pics.Clear();
pics.AddRange(date.Where(x => x != "teach" && x != "end"));
timer1.Interval = 5000;
timer1.Start();

Then you'll have to tell your Timer to display the next picture. Increase the counter, and reset it when necessary. Something like this should work. Modify as necessary.

private void timer1_Tick(object sender, EventArgs e)
{
    dialog.ImageLocation = string.Format("{0}/npc/{1}/{2}.png", folder, score_npc, pics[currentPic]);

    currentPic++;

    if (currentPic >= pics.Count)
        currentPic = 0;

    // Alternatively, stop the Timer when you get to the end, if you want
    // if (currentPic >= pics.Count)
    //     timer1.Stop();
}
Grant Winney
  • 65,241
  • 13
  • 115
  • 165