【问题标题】:Moving a picturebox with a timer使用计时器移动图片框
【发布时间】:2009-12-04 18:33:09
【问题描述】:

我试图通过每 20 毫秒更改其 Top 和 Left 属性来移动包含控件中的图片框。在黑色背景上它会更平滑一些,但是当将 BackgroundImage 分配给控件时,图片框会在其后面留下一条轨迹,直到几秒钟后重新绘制控件,然后突然减速然后向前发射,或者以锯齿状轨迹移动。

我认为,当重绘 PictureBox 控件时,更改其 left 和 top 属性的线程会暂停,直到重绘完成,这会导致它在重绘完成时将暂停的计时器循环的任何迭代排队.

有没有办法平滑图片框的运动?

谢谢 F

【问题讨论】:

  • 我将其更改为 System.Windows.Timer 并且移动显然更流畅,但我希望它发生在不同的线程上。

标签: c# gdi+


【解决方案1】:

我建议在一个控件中绘制图像,而不是在控件中移动。

创建一个自定义控件,覆盖 OnPaint 并在其中绘制您的“图片框”。如果你这样做,你也可以后台缓冲。通过调用 Graphics.FromImage() 从图像创建图形对象来执行此操作。在上面绘制,最后在绘制完成后调用 REAL 图形对象(在 eventArgs 中)上的 g.DrawImage。

【讨论】:

  • 这似乎对轨迹和锯齿状运动有所帮助。然而,我仍然遇到位图在移动几英寸后保持静止一两秒的问题。
  • 您的代码中是否存在错误的 Application.DoEvents()?这可以解释这种延迟。如果您不使用它,那么我想知道可能导致问题的原因。你能把它提取成一个小而完整的例子吗?
  • 我可以提一下,现在移动很清晰,而不是摇晃,但前提是自定义控件在其自己的单独应用程序中运行。我想在其中运行它的大型应用程序有另一个计时器,并且还做一些其他事情,所以与此同时其他事情正在接管。我会尝试在一个线程中运行该运动,如果这不起作用,我会就此与您联系。谢谢。
  • 您真的希望使用 GDI+ 将线程保持在最低限度,因为它是一个单线程图形库。
  • 还要仔细检查您的“主应用程序”,您没有使用 Windows.Forms.Timers,而您可能正在使用 System.Threading.Timers。 Windws.Forms.Timer 中的回调将使用 UI 线程,如果它正在触摸控件,这是必要的,如果不是,那么它会浪费宝贵的 UI 资源。
【解决方案2】:

我不确切知道如何解决该问题(除了切换到 WPF),但我可以说你得到的滞后来自移动 PictureBox 时正在更新的区域的失效。您想要做的是以某种方式回缓冲新位置并切换到缓冲区,而不是依靠 GDI 实时重绘。 HTH。

【讨论】:

    猜你喜欢
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多