Search code examples
c#bitmappicturebox

C# Update few Picture Boxes at the same time


I have 5 Picture Boxes in my application, and I update them at the same time. I want them to display 5 different Images and my programs code is right, but for some reason the picture boxes show all the same image...

Here's the code:

private System.Drawing.Bitmap DiceOne;
private System.Drawing.Bitmap DiceTwo;
private System.Drawing.Bitmap DiceThree;
private System.Drawing.Bitmap DiceFour;
private System.Drawing.Bitmap DiceFive;
private System.Drawing.Bitmap DiceSix;

public void Prepare()
{
    for (int i = 0; i < 5; i++)
        Dices[i] = new Dice();

    DiceOne = Properties.Resources.Würfel_1;
    DiceTwo = Properties.Resources.Würfel_2;
    DiceThree = Properties.Resources.Würfel_3;
    DiceFour = Properties.Resources.Würfel_4;
    DiceFive = Properties.Resources.Würfel_5;
    DiceSix = Properties.Resources.Würfel_6;
}

public void Roll()
{
    foreach (Dice dice in Dices)
        dice.RollTheDice();

    View.SuspendLayout();
    View.diceOnePictureBox.Image = DiceNumberToBmp(Dices[0].GetLastRolled());
    View.diceOnePictureBox.Update();
    View.diceTwoPictureBox.Image = DiceNumberToBmp(Dices[1].GetLastRolled());
    View.diceOnePictureBox.Update();
    View.diceThreePictureBox.Image = DiceNumberToBmp(Dices[2].GetLastRolled());
    View.diceOnePictureBox.Update();
    View.diceFourPictureBox.Image = DiceNumberToBmp(Dices[3].GetLastRolled());
    View.diceOnePictureBox.Update();
    View.diceFivePictureBox.Image = DiceNumberToBmp(Dices[4].GetLastRolled());
    View.diceOnePictureBox.Update();
    View.ResumeLayout(false);
}

private System.Drawing.Bitmap DiceNumberToBmp(int number)
{
    switch(number)
    {
        case 1:
            return DiceOne;
        case 2:
            return DiceTwo;
        case 3:
            return DiceThree;
        case 4:
            return DiceFour;
        case 5:
            return DiceFive;
        case 6:
            return DiceSix;
        default:
            return null;
    }
}

I've read some familier posts on the internet before, and tried to solve with with SuspendLayout, ResumeLayout, Updating the PictureBox.... Nothing worked for me.

My Dice class:

using System;

namespace KniffelGUI.Model
{
    public class Dice
    {

        private int LastRolled;

        public Dice()
        {
            RollTheDice();
        }

        public Dice(int fakeRoll)
        {
            LastRolled = fakeRoll;
        }

        public int RollTheDice()
        {
            LastRolled = new Random().Next(6) + 1;

            return LastRolled;
        }

        public int GetLastRolled()
        {
            return LastRolled;
        }

    }
}

Solution

  • The problem is in your Dice class, as suggested earlier by Barry O'Kane.

    Change it to:

    public class Dice
    {
    
        private int LastRolled;
        private static Random R = new Random();
    
        public Dice()
        {
            RollTheDice();
        }
    
        public Dice(int fakeRoll)
        {
            LastRolled = fakeRoll;
        }
    
        public int RollTheDice()
        {
            LastRolled = R.Next(6) + 1;
            return LastRolled;
        }
    
        public int GetLastRolled()
        {
            return LastRolled;
        }
    
    }
    

    Your symptom was occurring because of this line:\

    LastRolled = new Random().Next(6) + 1;
    

    When you create an instance of Random with the default constructor, it uses the current time as the seed. When you create multiple instances in rapid succession, they end up with the same seed and therefore won't get different numnbers.

    By declaring it as static, all instances of your class will use the same Random instance and get a different number upon each call.