在移动时触发连续事件时移动栏会冻结

时间:2013-12-13 11:14:48

标签: c# user-controls repaint

我有一个UserControl。我可以搬吧。

每次移动栏时,都会触发一个事件。当我没有订阅任何事件时,一切都很好。当我移动横杆时,横杆被绘制在正确的位置。

但是当我订阅某些内容时,控件的paint方法似乎太慢了。我的酒吧不动,但我的活动正在开火。当您停止移动条形时,它会再次涂在正确的位置。

我如何解决这个冻结问题?在抽奖之后才像火一样?我试图在OnPaint方法结束时调用该事件,但这并没有解决问题。

protected override void OnPaint(PaintEventArgs e)
{
  Bitmap btm = new Bitmap(_drawRectangle.Width, _drawRectangle.Height);
  using (Graphics gfx = Graphics.FromImage(btm))
  {
    ... //draw bar, etc.
  }
  this.drawbox.Image = btm;

  base.OnPaint(e);

  //if (PositionChanged != null) PositionChanged(...);
}

当每次移动都没有触发事件时,这不是问题。它也可以是酒吧的每一次抽奖。

1 个答案:

答案 0 :(得分:3)

Paint是一种低优先级操作,只有在不需要其他任何操作时才会发生。所以问题不在于你的OnPaint()方法很慢,而是你编写的“订阅东西”代码。如果它足够慢,那么当“某些”代码完成时,可能还有另一个MouseMove通知等待处理。这导致它再次运行。因此,在您停止移动鼠标之前,不再进行绘画并且UI看起来“冻结”。

您可以通过在您使用的任何事件中调用this.Update()来解决问题。这迫使OnPaint()运行。这种权衡可能会引人注目,“酒吧”会变得更加生涩。你必须编写更有效的代码才能让它再次流畅。

值得注意的是,您的位图绘制代码看起来非常糟糕,分配PictureBox的Image属性会导致另一个绘制事件触发。取而代之的是直接绘制到e.Graphics,所以根本不需要这个图片框。在构造函数中设置this.DoubleBuffered = true以抑制闪烁。