没有 OnPaint 无效

Invalidate without OnPaint

我正在尝试在 Win Forms 中制作动画,我尝试了一种不同于在 timer_elapsed 处理程序中调用 Invalidate() 然后在 OnPaintHandler 中执行操作的方法。

我直接在pictureBox上画了一张图,然后在timer_ticks的时候调用了Invalidate,然后在更新的位置手动重画了图

static void tmrMoving_Elapsed(object sender, EventArgs e, Train t)
{
    MainForm.playBox.Invalidate();

    g.DrawImage(t.components[i], new Rectangle(
                new Point(t.nextVagoonPositionX * 20, t.nextVagoonPositionY * 20), 
                new Size(20, 20)));
    t.nextVagoonPositionX += 1;
    t.nextPositionX = -1;
}

我有一个问题,当计时器滴答作响时,有时会绘制所需的图像,有时不会,例如有 30% 的机会不绘制(我有 1 秒的计时器间隔,所以我可以看到它),即使对象正在移动或只是在同一位置。

我尝试过的事情:

1.Setting Invalidate() args 中的一个区域 -> 图像在旧图像旁边绘制了很多次(因此它没有在所需位置重新绘制,因为旧图像保留在它们的位置)

2.Calling Update() 或 Refresh() 或两者都在无效之后-> 从未显示任何图像

3.Combining Update() 或 Refresh() 或两者都无效(矩形区域)-> 从未显示图像

4.Setting DoubleBuffering true -> 无效

5.Fiddling 与 this.SetStyle(ControlStyles.UserPaint, 真); -> 没有效果(顺便说一句,甚至不确定它的作用。)

您不应该在 OnPaint 处理程序之外直接绘制 UI 控件。在 "lower level" WinAPI 中,您只能在 WM_PAINT 上绘制到屏幕,这会引发 OnPaint 事件。

将绘图代码 (g.DrawImage(...)) 移出计时器处理程序并移至 OnPaint 处理程序中。