Simultaneous update of multiple image boxes

I have four PictureBoxes

(each PictureBox represents one cube) and a Timer that changes every 100ms the original images (loaded into memory as List<Bitmap> imagesLoadedFromIncludedResources

).

enter image description here

code:

private List<PictureBox> dices = new List<PictureBox>();

private void timer_diceImageChanger_Tick(object sender, EventArgs e)
{
    foreach (PictureBox onePictureBox in dices)
    {
        oneDice.WaitOnLoad = false;
        onePictureBox.Image = //... ;
        oneDice.Refresh();
    }
}  

      

I need to change all the images at once - at this point you can see that the images change from left to right with a slight delay .

I tried one Thread

for each option PictureBox

(using the Control.Invoke

method from this answer ) - it's visually a little better, but not perfect.

+3


source to share


3 answers


You can try to pause your form layout logic:



SuspendLayout();
// set images to pictureboxes
ResumeLayout(false);

      

+4


source


Parallel.ForEach
(
    dices,
    new ParallelOptions { MaxDegreeOfParallelism = 4 },
    (dice) =>
    {
        dice.Image = ...;
        dice.WaitOnLoad = false;
        dice.Refresh();
    }
);

      

The problem is that UI controls can only be accessed from the UI thread. If you want to use this approach, you must create a copy of your PictureBoxes and then replace the UI after the operation is complete.



Another approach would be to create two PictureBoxes, the first one would be on top of the other (hiding the last one) ... you change all the images, and then once processing is complete, you iterate over all those in the back, putting them on top, which will result in a smaller delay.

0


source


I would approach this differently - it's been a while since I've played with WinForms files, but I probably have more control over the rendering of images.

In this example, I have all the images in a single source bitmap file arranged vertically, stored as a resource in an assembly:

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private Timer timer;

        private Bitmap dice;

        private int[] currentValues = new int[6];

        private Random random = new Random();

        public Form1()
        {
            InitializeComponent();
            this.timer = new Timer();
            this.timer.Interval = 500;
            this.timer.Tick += TimerOnTick;

            this.dice = Properties.Resources.Dice;
        }

        private void TimerOnTick(object sender, EventArgs eventArgs)
        {
            for (var i = 0; i < currentValues.Length; i++)
            {
                this.currentValues[i] = this.random.Next(1, 7);
            }

            this.panel1.Invalidate();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (this.timer.Enabled)
            {
                this.timer.Stop();
            }
            else
            {
                this.timer.Start();
            }
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.Clear(Color.White);

            if (this.timer.Enabled)
            {
                for (var i = 0; i < currentValues.Length; i++)
                {
                    e.Graphics.DrawImage(this.dice, new Rectangle(i * 70, 0, 60, 60), 0, (currentValues[i] - 1) * 60, 60, 60, GraphicsUnit.Pixel);
                }
            }
        }
    }
}

      

Source here if it helps: http://sdrv.ms/Wx2Ets

0


source







All Articles