Panel.Invalidate未由OnPaint处理

时间:2015-12-15 12:57:59

标签: c# .net winforms event-handling

我有一个继承Panel Control的类,其目的是允许我在透明背景上绘制一些简单的几何图形。该对象定义如下:

 public class TrackOverlay : Panel
{
    private ControlWindow parentForm;
    ...
    public TrackOverlay(PictureBox parent)
    {
        parentForm = (ControlWindow)(parent.Parent);
        // Create a transparent form on top of <parent>
        ...
        this.Size = parent.ClientSize;
        this.Location = parent.PointToScreen(Point.Empty);
        parent.Parent.Controls.Add(this);
}

当某个事件发生时(在BackgroundWorker的上下文中,如果这很重要)我调用Invalidate方法,并期望输入以下重写的Paint方法,定义如下:

new private void Paint(object sender, PaintEventArgs e)
    {
        using (Graphics graphics = this.CreateGraphics())
        {
          // do graphics stuff
        }
    }

使用调试器,我看到调用了Invalidate(),但是Paint()不是。这似乎与here描述的情况类似,但是那里提到的建议都没有帮助我。 在this post之后,我重新定义了函数签名,如下所示:

protected override void OnPaint(PaintEventArgs e)

但仍然没有快乐。如何让事件处理程序发生?

2 个答案:

答案 0 :(得分:2)

   parent.Parent.Controls.Add(this);

这不符合你的想法。您的叠加层不会覆盖任何内容,它位于 PictureBox下面。所以你的OnPaint()方法永远不会被调用,因为用户无法看到它,所以不需要绘制。

不是唯一的问题,你也不会得到你希望的透明度。您将通过透明部分看到表单,而不是图片框中的图像。您必须将图片框设为父级。换句话说:

   this.Location = Point.Empty;
   parent.Controls.Add(this);
   parent.Controls.SetChildIndex(this, 0);

最后一行肯定不是必需的,但显示了如何确保控件与另一个控件重叠。

检查this post中的PictureContainer类,了解在设计时工作的方法。

答案 1 :(得分:0)

  

调用Invalidate方法不会强制执行同步绘制;要强制执行同步绘制,请在调用Invalidate方法后调用Update方法。如果在没有参数的情况下调用此方法,则会将整个客户区添加到更新区域。

来自MSDN Control.Invalidate()方法。