C# PictureBox刷新会导致上面的层闪烁
我试图从端口读取数据并在拨号盘上显示。背景是一个图像盒,其中包含一个给出读数的圆形刻度的图像,并使用线型表示刻度盘。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
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 ));
}