7

我重写了 OnPaint 方法以在屏幕上绘制椭圆。

    protected override void OnPaint(PaintEventArgs e)
    {
        MessageBox.Show("Paint");
        if (debugStarted)
        {
            int y = rtbLogicCode.PlaceToPoint(new Place(0, debugLine)).Y;
            if (rtbLogicCode.GetVisibleState(debugLine).ToString() == "Visible")
            {
                e.Graphics.FillEllipse(new LinearGradientBrush(new Rectangle(0, y, 15, 15), Color.LightPink, Color.Red, 45), 0, y, 15, 15);
            }
            base.OnPaint(e);
        }
    }

    private void rtbLogicCode_Scroll(object sender, ScrollEventArgs e)
    {
        this.Invalidate();
    }

滚动事件(在 Richtextbox 上)得到了正确处理,但即使我使表单无效,它也没有调用 OnPaint 函数(没有显示消息框)。

这可能是什么原因?

编辑:我忘了提到在子窗体的初始化函数(使用 MDI 属性作为主窗体的控件添加),我设置了以下样式:

 private void LogicCodeInit()
    {


            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.UserPaint, true);


    }

Edit2:我也忘了提到子窗体是作为 TabControl 的控件添加的。然后将 TabControl 添加为主窗体的控件。

4

3 回答 3

13

Update之后调用InvalidateInvalidate只有当它有焦点时才重新绘制表单,它可能没有得到焦点,因为它是作为一个TabControl孩子添加的。

MSDN 文档

调用 Invalidate 方法不会强制同步绘制;要强制同步绘制,请在调用 Invalidate 方法后调用 Update 方法。不带参数调用此方法时,会将整个客户区添加到更新区域。

于 2012-07-09T07:04:18.103 回答
1

调用Invalidate控件将导致部分或全部无效,表明它需要“有时”更新,但不会导致该更新立即发生。调用Update将导致控件的任何已失效部分立即重绘。调用Refresh将结合上述效果。每当系统空闲时,它将为具有任何无效区域的控件调用进程更新。

Invalidate方法在按顺序执行许多更改控件应显示内容的方法的情况下很有用。不必在更改控件的每个方法之后都重新绘制控件,而是可以让更改控件的方法使那些需要重新绘制的部分无效。一旦完成了所有可能更改控件的方法,就可以使用Update重绘控件中已失效的那些部分(如果有)。如果重绘控件需要 1/100 秒,并且需要对其执行 50 次操作,则延迟和合并更新可能会在似乎即时更新的控件和需要半秒的控件之间产生差异。

于 2012-10-20T21:02:25.917 回答
0

可能不被调用的主要原因OnPaint是如果您ControlStyle不包含UserPaint. 如果您确实设置了它,我会希望您提及这一点,所以我假设您没有。SetStyle在这种情况下,在您的构造函数中添加一个调用。

于 2012-07-09T06:21:48.377 回答