如何在Windows窗体中平滑重新绘制Panel

问题描述 投票:2回答:1

如何平滑地重新粉刷面板?

我正在使用一个计时器,每300毫秒使面板(panel1.Invalidate();)无效,然后在panel1_Paint事件中,我向该面板添加图像,问题是它看起来像在跳跃,我需要移动尽我所能尽快获得一张图像。

这是截屏问题的链接:http://screencast.com/t/HdtIV99YN

 private void panel1_Paint(object sender, PaintEventArgs e)
            {
                PaintMapObstacles(e);
                PaintMapStartAndGoal(e);

                if (trayectoryIndex < 1000)
                {
                   MapPoint point =  GetTrayectoryPoint(0, trayectoryIndex);
                   e.Graphics.DrawImage(new Bitmap("robot.jpg"), point.X*squareSize, point.Y*squareSize, 60, 60);
                   trayectoryIndex++;
               }
            }
     private void PaintMapStartAndGoal(PaintEventArgs e)
            {
                MapPoint start = new MapPoint { X = 0, Y = 0 };
                MapPoint goal = new MapPoint { X = 7, Y = 8 };
                   // e.Graphics.DrawImage(new Bitmap("start.jpg"), start.X * squareSize, start.Y * squareSize, 60, 60);
                    e.Graphics.DrawImage(new Bitmap("goal.jpg"), goal.X * squareSize, goal.Y * squareSize, 60, 60);
                    isFirstRun = true;
            }


        private void PaintMapObstacles(PaintEventArgs e)
            {

                foreach (MapPoint mpoint in obstacles.Obstacles)
                {
                    e.Graphics.DrawImage(new Bitmap("obstacle.png"), mpoint.X * squareSize, mpoint.Y * squareSize, 60, 60);  
                }
            }

         private void PanelTimer_Tick(object sender, EventArgs e)
            {

                panel1.Invalidate();
            }
c# winforms panel paint paintevent
1个回答
3
投票

它被称为“闪烁”,当您从头开始重新绘制窗口时,它始终存在。它在您的程序中特别值得注意,因为您的绘画代码效率很低。您会看到绘制了窗户的背景,从而擦除了旧画。然后慢慢将位图绘制回背景。擦除步骤肉眼可见,看起来像闪烁。

闪烁的一般解决方法是双缓冲,首先将窗口内容组成为位图,然后迅速将位图拖到屏幕上。它是Winforms的内置功能,DoubleBuffered属性将其打开。默认情况下,Panel类未启用双缓冲,它被设计为一个容器控件,除了绘制背景之外,它本身不会进行绘制。 PictureBox在您的情况下也可以正常工作,默认情况下启用了双缓冲。或者,您可以为Panel类shown here启用双缓冲。

您确实希望最终解决绘画代码中的问题,除了它非常慢之外,它还会因OutOfMemoryException导致程序崩溃。由您使用Bitmap类的方式引起的问题,应在使用它后将其清除。始终对System.Drawing对象使用using

语句。

您只需创建一次位图就可以更快,表单构造器是最好的地方。通过预缩放位图以使其适合网格并注意像素格式,可以使其快速[[really

。 PixelFormat.Format32bppPArgb与几乎任何现代视频适配器的帧缓冲区格式直接兼容,可以将位图直接复制到帧缓冲区中,而无需进行转换。比所有其他格式快十倍。转换代码is here
© www.soinside.com 2019 - 2024. All rights reserved.