C# PictureBox刷新会导致上面的层闪烁

C# PictureBox刷新会导致上面的层闪烁,c#,winforms,picturebox,C#,Winforms,Picturebox,我试图从端口读取数据并在拨号盘上显示。背景是一个图像盒,其中包含一个给出读数的圆形刻度的图像,并使用线型表示刻度盘。PictureBox已“发送到背面”,以允许线型的可见性。随函附上代表代码: 如果我这样做: private void timer1_Tick(object sender, EventArgs e) { ang += 2.0 * Math.PI / 180.0; lineShape1.X1 = Convert.ToInt32(line

我试图从端口读取数据并在拨号盘上显示。背景是一个图像盒,其中包含一个给出读数的圆形刻度的图像,并使用线型表示刻度盘。PictureBox已“发送到背面”,以允许线型的可见性。随函附上代表代码: 如果我这样做:

    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的刷新功能,则拨号盘会闪烁。我尝试过使用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();
    }

为了解决实际问题,不可能增加间隔。如何显示刻度盘的平稳变化?

GDI+通常具有这种效果。这就是为什么WinForms通常被WPF和XAML取代的原因。我认为,IIRC,
PictureBox
尤其容易出现这个问题。您需要做的是在
PictureBox
的图像上执行所有的“绘制”。完成所有绘图后,使用新图像更新
PictureBox


但是,如果您真的很快地绘制新图像并随后更新
PictureBox
,您仍然可能会出现闪烁
PictureBox
不是为这个用例设计的。它的设计或多或少是为了显示一个静态图像(或一个可能偶尔改变,但频率不高的图像)。

GDI+通常具有这种效果。这就是为什么WinForms通常被WPF和XAML取代的原因。我认为,IIRC,
PictureBox
尤其容易出现这个问题。您需要做的是在
PictureBox
的图像上执行所有的“绘制”。完成所有绘图后,使用新图像更新
PictureBox


但是,如果您真的很快地绘制新图像并随后更新
PictureBox
,您仍然可能会出现闪烁
PictureBox
不是为这个用例设计的。它的设计或多或少是为了显示一个静态图像(或一个可能偶尔改变但频率不高的图像)。

正如@Hans Passant所建议的,您不应该使用线型对象。这是实现其建议的代码示例(快速,未经测试):


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

正如@Hans Passant所建议的,您不应该使用LineShape对象。这是实现其建议的代码示例(快速,未经测试):


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

不要使用LineShape。而是在图片框的“绘制事件”中使用e.Graphics.DrawLine()。调用pictureBox1.Invalidate()请求重新绘制。我不熟悉使用pictureBox组件。所以在拉里添加代码之前,我无法理解这个回复。多亏了你们两个……不要用线型。而是在图片框的“绘制事件”中使用e.Graphics.DrawLine()。调用pictureBox1.Invalidate()请求重新绘制。我不熟悉使用pictureBox组件。所以在拉里添加代码之前,我无法理解这个回复。谢谢你们两位,非常感谢。虽然drawLine绘制的线条不是很平滑,但它还是起到了主要作用。即使间隔10毫秒,也没有明显的闪烁现象:)该死,我忘了这个。。。我对代码进行了一点更新,添加了抗锯齿代码。很高兴它有帮助,请欣赏!谢谢。虽然drawLine绘制的线条不是很平滑,但它还是起到了主要作用。即使间隔10毫秒,也没有明显的闪烁现象:)该死,我忘了这个。。。我对代码进行了一点更新,添加了抗锯齿代码。很高兴它有帮助,请欣赏!这个答案没有用。这无助于解决问题。这个答案没有用。这无助于解决问题。
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 ));
}