C# Invalidate 没有调用paint方法

问题描述 投票:0回答:4

我重写了 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 将作为主窗体的控件添加。

c# .net winforms paint invalidation
4个回答
13
投票

Update
之后致电
Invalidate
Invalidate
仅当表单具有焦点时才重新绘制表单,它可能不会获得焦点,因为它是作为
TabControl
子项添加的。

来自 MSDN 文档

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


1
投票

在控件上调用

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

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


0
投票

无法调用

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


0
投票

需要检查的事情:当我忘记将自定义控件添加到 InitializeComponent 方法中的 Controls 集合中时,我在使用新的自定义控件时遇到了大致相同的问题。

© www.soinside.com 2019 - 2024. All rights reserved.