如何防止Windows窗体文本框在调整大小时闪烁?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (15)

有很多关于Windows窗口闪烁的文章。大多数人建议设置DoubleBuffered = true或者设置一堆ControlStyle。然而,所有这些都无助于减少文本框的闪烁。

那么,是否有什么何方法来修复文本框中文本的闪烁?

提问于
用户回答回答于

我通常使用RichTextBox而不是多行文本框。通过将DetectUrls-和ShtcutsEnable-属性设置为false,RTB的行为非常类似于文本框,并且...它无闪烁...

用户回答回答于

在Windows窗体中,DoubleBuffed属性不影响子控件(如文本框)。相反,它只影响它设置的窗体或面板。

如果要对窗体上的子元素进行双缓冲,则需要实现手动双缓冲。

调整闪烁文本框的大小,需要以某种方式将文本框呈现给后台缓冲区,然后将其显示为缓冲更新的一部分。如果可能的话,我不认为这容易。

更新

其他一些答案说这是Windows窗体的一个具体问题。这是不正确的,它实际上是更深的,并且是由WindowsGDI引起的。例如,打开记事本/写字板等,粘贴大量文本,调整窗口大小,注意到同样的闪烁问题。

下面是我几年前做类似事情时使用的一个基本解决方案。它是一个简单的表单,包含一个多行文本框和一个从Panel继承的自定义类。两个控件的位置和大小相同。它使用窗体ResignBegin和ResignEnd在调整大小时显示面板,而使用TextBox显示。这并不完美,但它确实消除了闪烁。

   public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Bitmap bm = null;

        private void textBox1_Resize(object sender, EventArgs e)
        {

            Graphics g = textBox1.CreateGraphics();

            if (g.VisibleClipBounds.IsEmpty == false)
            {
                bm = new Bitmap((int)g.VisibleClipBounds.Width, (int)g.VisibleClipBounds.Height);

                textBox1.DrawToBitmap(bm, new Rectangle(0, 0, (int)g.VisibleClipBounds.Width, (int)g.VisibleClipBounds.Height));

            }

            g.Dispose();


        }

        private void panelDB1_Paint(object sender, PaintEventArgs e)
        {
            if (bm != null)
            {
                e.Graphics.DrawImageUnscaled(bm, 0, 0,bm.Width,bm.Height );
            }
        }

        private void Form1_ResizeBegin(object sender, EventArgs e)
        {
            panelDB1.BringToFront();  
        }

        private void Form1_ResizeEnd(object sender, EventArgs e)
        {
            panelDB1.SendToBack();   
        }
}

class PanelDB : Panel
{
    public PanelDB()
    {
        this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer,true);       
        //this.DoubleBuffered = true; 

    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
    }
}

扫码关注云+社区