Search code examples
c#buttonclickpictureboxbackcolor

Change picturebox backcolor for x amount of time


I'm trying to change for a preset amount of time the backcolor of a pictureBox when the user clicks a button. I tried to use timers but I saw this Stopwatch on another question. The problem is that the code inside the loop isn't running properly and it keeps crashing.How can I make this work? Code below

private void b_click(object sender, EventArgs e)
{
    Button button = sender as Button;
    Dictionary <Button, PictureBox> buttonDict= new Dictionary<Button, PictureBox>();
    //4 buttons
    buttonDict.Add(bRED, pbRED);
    buttonDict.Add(bBlue, pbBLUE);
    buttonDict.Add(bGREEN, pbGREEN);
    buttonDict.Add(bYELLOW, pbYELLOW);
    Stopwatch s = new Stopwatch();
    s.Start();
    while (s.Elapsed < TimeSpan.FromSeconds(0.5))
    {
        buttonDict[button].BackColor = Color.Black;
        label1.Text = "black";//This part does run
    }
    buttonDict[button].BackColor = Color.White; //the pictureBox does turn white
    s.Stop();
}

Solution

  • Use Timer instead of Stopwatch :

    private void b_Click(object sender, EventArgs e)
    {
      Button button = sender as Button;
      Dictionary<Button, PictureBox> buttonDict = new Dictionary<Button, PictureBox>();
      //4 buttons
      buttonDict.Add(bRED, pbRED);
      buttonDict.Add(bBlue, pbBLUE);
      buttonDict.Add(bGREEN, pbGREEN);
      buttonDict.Add(bYELLOW, pbYELLOW);
      Timer timer = new Timer();
      timer.Interval = 500;
      timer.Tick += (o, args) =>
      {
        buttonDict[button].BackColor = Color.White;
        timer.Stop();
        timer.Dispose();
      };
      buttonDict[button].BackColor = Color.Black;
      label1.Text = "black";
      timer.Start();
    }
    

    Another possibilities, using Task.Run:

    private void b_Click(object sender, EventArgs e)
    {
      Button button = sender as Button;
      Dictionary<Button, PictureBox> buttonDict = new Dictionary<Button, PictureBox>();
      //4 buttons
      buttonDict.Add(bRED, pbRED);
      buttonDict.Add(bBlue, pbBLUE);
      buttonDict.Add(bGREEN, pbGREEN);
      buttonDict.Add(bYELLOW, pbYELLOW);
      buttonDict[button].BackColor = Color.Black;
      label1.Text = "black";
      Task.Run(() =>
      {
        Thread.Sleep(500);
        Invoke(new MethodInvoker(() =>
        {
          buttonDict[button].BackColor = Color.White;
        }));
      });
    }