Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 同时更新多个pictureboxes_C#_.net_Winforms_Picturebox - Fatal编程技术网

C# 同时更新多个pictureboxes

C# 同时更新多个pictureboxes,c#,.net,winforms,picturebox,C#,.net,Winforms,Picturebox,我有四个图片盒(每个图片盒代表一个骰子)和一个每100毫秒更改一次的源图片(作为列表图片加载到内存中,从包含的资源中加载) 代码: 私有列表骰子=新列表(); 私有无效计时器\u diceImageChanger\u勾号(对象发送方,事件参数e) { foreach(PictureBox一个PictureBox在骰子中) { oneDice.WaitOnLoad=false; onePictureBox.Image=/; oneDice.Refresh(); } } 我需要一次更改所有图

我有四个
图片盒
(每个图片盒代表一个骰子)和一个每100毫秒更改一次的源图片(作为
列表图片加载到内存中,从包含的资源中加载)

代码:

私有列表骰子=新列表();
私有无效计时器\u diceImageChanger\u勾号(对象发送方,事件参数e)
{
foreach(PictureBox一个PictureBox在骰子中)
{
oneDice.WaitOnLoad=false;
onePictureBox.Image=/;
oneDice.Refresh();
}
}  
我需要一次更改所有图像-此时,您可以看到图像是以较小的延迟从左向右更改的

我为每个
PictureBox
(使用来自的方法)尝试了一个
线程的变体,它在视觉上稍好一些,但并不完美

Parallel.ForEach
(
    dices,
    new ParallelOptions { MaxDegreeOfParallelism = 4 },
    (dice) =>
    {
        dice.Image = ...;
        dice.WaitOnLoad = false;
        dice.Refresh();
    }
);
问题是UI控件只能从UI线程访问。如果要使用这种方法,必须创建PictureBox的副本,然后在操作完成后替换UI


另一种方法是创建两个PictureBox,第一个正好位于另一个的顶部(隐藏后者)。。。您可以更改所有图像,然后在处理完成后,迭代背面的所有图像,将它们放在顶部,这样会减少延迟。

您可以尝试暂停表单的布局逻辑:

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

我会用不同的方法来处理这个问题——我已经有一段时间没有玩WinForms了,但是我可能会对图像的渲染有更多的控制

在本例中,我将所有图像垂直堆叠在一个源位图中,并作为资源存储在程序集中:

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);
                }
            }
        }
    }
}
命名空间窗口窗体应用程序1
{
公共部分类Form1:Form
{
私人定时器;
私人位图骰子;
私有int[]当前值=新int[6];
私有随机=新随机();
公共表格1()
{
初始化组件();
this.timer=新计时器();
此.timer.Interval=500;
this.timer.Tick+=TimerOnTick;
this.dice=Properties.Resources.dice;
}
私有void TimerOnTick(对象发送方,EventArgs EventArgs)
{
对于(var i=0;i

如果有帮助,源代码就在这里:

您是否预缓存了要关闭的
位图
对象?如果每次从磁盘加载,都会有一点延迟。是的,我将
格式中的预缓存加载(…)
位图
放入
列表中,源图像有多大?我无法想象屏幕截图中显示的这么小的东西会有明显的延迟(假设源图像真的那么小)。请尝试使用
foreach(PictureBox-onePictureBox-in-dices.AsParallel()
事实上,图像稍大一些:“值1”=2,6KB,“值6”=9KB,所有图像的总大小约为38KB。
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);
                }
            }
        }
    }
}