我必须在2条(图像)之间绘制一个移动的箭头图像(使用C#代码VS2008)。我尝试了两种方法:
问题在于闪烁。每当我移动箭头图像(或重绘点)附近的图像(实际上很少有其他图像作为条形图)闪烁。我试着调用invalidate(rect),认为它只会重绘给定的矩形,但是一旦箭头图像越过这些条,一切都会闪烁。这看起来不太好。如何以平滑的方式移动此箭头图像。 PLS。建议。或者我应该采用另一种方法?
//代码:**
公共部分类Form1:表单 { 私有位图bitmapAntenna; private Bitmap bitmapArrow;
public Form1()
{
bitmapAntenna = new Bitmap("D:\\AntennaBar.JPG");
bitmapArrow = new Bitmap("D:\\Arrow.JPG");
}
private void DrawAntennaImages(int antennaNo)
{
Graphics grph = this.CreateGraphics();
if (1 == antennaNo)
{
grph.DrawImage(bitmapAntenna, new RectangleF(350, 300, bitmapAntenna.Width*(1.00F), bitmapAntenna.Height*(1.00F))) ;
}
else
grph.DrawImage(AntennaImage, new Point(550, 300));
}
private void DrawArrowImages(int X)
{
Graphics grph = this.CreateGraphics();
grph.DrawImage(bitmapArrow, new Point(380 + X, 350));
}
private void PaintHandler(Object sender, System.Windows.Forms.PaintEventArgs e)
{
DrawAntennaImages(1);
DrawAntennaImages(2);
}
private void button_Click(object sender, EventArgs e)
{
for (int i = 1; i < 40; i++)
{
// Note: first draw antenna 1 image, arrow image then antenna 2 image so that arrow will overlap
// only antenna 1 image only.
DrawAntennaImages(1); // Draw Antenn 1 image
DrawArrowImages(i * 2); // Draw Arrow image
DrawAntennaImages(2); // Draw Antenn 2 image
System.Threading.Thread.Sleep(25); // Sleep before drawing next time ..
}
this.Invalidate(); // If I don't call this, arrow image does not elope after last draw
}
}
//在设计师
中this.Paint + = new System.Windows.Forms.PaintEventHandler(this.PaintHandler);
//代码 *
由于 RPS
答案 0 :(得分:1)
我在这里假设WinForms:
您是否尝试过使用double buffering?
您可以尝试implement your own double buffering。
不要指望奇迹在这里; WinForms从来没有打算做过这样的事情。
答案 1 :(得分:1)
只需打开表单的双缓冲
myCanvasForm.SetStyle(
ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.DoubleBuffer,true);
或您使用的控件。
myCanvasControl.DoubleBuffered = true;
Here is some more information关于Windows窗体和GDI +中的双缓冲。
哦,顺便说一下:WPF中不存在这类问题。在图形质量和易用性方面(对于你正在做的简单事情),WPF远远优于Windows窗体和GDI +。
这是你如何在WPF / XAML中绘制移动的恐怖:
<Canvas>
<Canvas.Resources>
<Storyboard x:Key="OnLoaded1">
<DoubleAnimationUsingKeyFrames RepeatBehavior="Forever" Storyboard.TargetProperty="(Canvas.Left)" Storyboard.TargetName="blockArrow">
<EasingDoubleKeyFrame KeyTime="0:0:6" Value="500"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Canvas.Resources>
<ed:BlockArrow x:Name="blockArrow" Stroke="Black" Width="100" Height="50" Canvas.Left="0" Canvas.Top="200"/>
</Canvas>
答案 2 :(得分:0)
如果您PictureBox
尝试设置DoubleBuffering = true
。如果此闪烁仍然存在,请在屏幕上绘制Bitmap
之前将所有内容绘制到Bitmap
上。
答案 3 :(得分:0)
我们在WinForms中制作动画,并且不会因为我们的技术而出现任何闪烁,这是这样的:
timer.Interval = 1000/25;
向Tick事件添加回调方法:timer.Tick += new EventHandler(animateCallback)
animateCallback
应更新Arrow实例的坐标并调用Invalidate()以让.NET图形系统调用控件的Paint方法。使用System.Windows.Forms.Timer类对于避免闪烁至关重要。此计时器在UI线程中运行。这意味着,您获得的回调位于UI线程中。因此,当您在animateCallback方法中更新箭头坐标时,系统不会进行任何绘图。