PictureBox Refresh导致上面的图层闪烁

时间:2014-07-27 18:26:41

标签: c# winforms picturebox

我正在尝试从端口读取数据并在表盘上显示。背景是一个PictureBox,其中包含一个给出读数的圆形刻度图像,并且一个Lineshape用于表示刻度盘。 PictureBox已被发送回'允许Lineshape的可见性。我附上代表性代码: 如果我这样做:

    private void timer1_Tick(object sender, EventArgs e)
    {
        ang += 2.0 * Math.PI / 180.0;
        lineShape1.X1 = Convert.ToInt32(lineShape1.X2 - r * Math.Sin(ang));
        lineShape1.Y1 = Convert.ToInt32(lineShape1.Y2 - r * Math.Cos(ang));

    }

然后它在PictureBox上留下痕迹。

但如果我使用PictureBox的Refresh功能,则表盘会闪烁。我尝试过10,15,20,50和100的定时器间隔,但问题仍然存在。

    private void timer1_Tick(object sender, EventArgs e)
    {
        ang += 2.0 * Math.PI / 180.0;
        lineShape1.X1 = Convert.ToInt32(lineShape1.X2 - r * Math.Sin(ang));
        lineShape1.Y1 = Convert.ToInt32(lineShape1.Y2 - r * Math.Cos(ang));
        pictureBox1.Refresh();
    }

出于实际问题,不可能增加间隔。我该怎么做才能显示表盘的平滑变化?

2 个答案:

答案 0 :(得分:4)

正如@Hans Passant建议的那样,你不应该使用LineShape对象。这是一个实现他的建议的代码示例(快速,未经测试):

private void timer1_Tick(object sender, EventArgs e)
{
    pictureBox1.Invalidate();
}

void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    ang += 2.0 * Math.PI / 180.0;
    var X1 = Convert.ToInt32(X2 - r * Math.Sin(ang));
    var Y1 = Convert.ToInt32(Y2 - r * Math.Cos(ang));

    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    e.Graphics.DrawLine(
        new Pen(Color.Yellow, 1f),
        new Point(X1, Y1), 
        new Point(X2, Y2 ));
}

另外,尝试设置this.DoubleBuffered = true;以避免闪烁问题。

答案 1 :(得分:0)

众所周知,GDI +具有这种效果。这就是WinForms通常被WPF和XAML取代的原因。我认为,IIRC,PictureBox特别容易出现这个问题。您需要做的是执行所有"绘图"在PictureBox的{​​{1}}个图像中的图像上。完成所有绘图后,使用新图像更新PictureBox

但是,如果您真的很快地绘制新图像并随后更新PictureBox,那么您仍然可能会出现闪烁现象。 PictureBox仅仅是针对此用例而设计的。它或多或少地被设计为显示静态图像(或者可能偶尔改变但不是高频率的图像)。