views:

1157

answers:

5

I have a RichTextBox where I need to update the Text property frequently, but when I do so the RichTextBox "blinks" annoyingly as it refreshes all throughout a method call. I was hoping to find an easy way to temporarily suppress the screen refresh until my method is done, but the only thing I've found on the web is to override the WndProc method. I've employed this approach, but with some difficulty and side effects, and it makes debugging harder, too. It just seems like there's got to be a better way of doing this. Can someone point me to a better solution? Thanks!

A: 

Try this out:

myRichTextBox.SuspendLayout();
DoStuff();
myRichTextBox.ResumeLayout();
BKimmel
you may also have to add myRichTextBox.Enabled = false; and the later Enabled = true;
Geoff
SuspendLayout() doesn't really help here.
DK
A: 

Could you just store the Text into a string, do your manipulations on the string, and at the end of the method, store it back into the Text property?

Howler
+2  A: 

Found here: http://bytes.com/forum/thread276845.html

I ended up sending a WM_SETREDRAW via SendMessage to disable then reenable followed by an Invalidate() after I finished updating. That seemed to work.

I've never tried this method. I have written an application with a RTB that has syntax highlighting and used the following in the RTB class:

protected override void WndProc(ref Message m)
{
 if (m.Msg == paint)
 {
  if (!highlighting)
  {
   base.WndProc(ref m); // if we decided to paint this control, just call the RichTextBox WndProc
  }
  else
  {
   m.Result = IntPtr.Zero; // not painting, must set this to IntPtr.Zero if not painting otherwise serious problems.
  }
 }
 else
 {
  base.WndProc(ref m); // message other than paint, just do what you normally do.
 }
}

Hope this helps.

BoltBait
WM_SETREDRAW worked for me. Should be the same as LockWindowUpdate.
DK
+2  A: 

I would suggest looking at LockWindowUpdate


[DllImport("user32.dll", EntryPoint="LockWindowUpdate", SetLastError=true,
ExactSpelling=true, CharSet=CharSet.Auto,
CallingConvention=CallingConvention.StdCall)]
+2  A: 

I asked the original question, and the answer that worked best for me was BoltBait's use of SendMessage() with WM_SETREDRAW. It seems to have fewer side effects than the use of the WndProc method, and in my application performs twice as fast as LockWindowUpdate.

Within my extended RichTextBox class, I just added these two methods, and I call them whenever I need to stop restart repainting while I'm doing some processing. If I were wanting to do this from outside of the RichTextBox class, I think it would work by just replacing "this" with the reference to your RichTextBox instance.

    private void StopRepaint()
    {
        // Stop redrawing:
        SendMessage(this.Handle, WM_SETREDRAW, 0, IntPtr.Zero);
        // Stop sending of events:
        eventMask = SendMessage(this.Handle, EM_GETEVENTMASK, 0, IntPtr.Zero);
    }

    private void StartRepaint()
    {
        // turn on events
        SendMessage(this.Handle, EM_SETEVENTMASK, 0, eventMask);
        // turn on redrawing
        SendMessage(this.Handle, WM_SETREDRAW, 1, IntPtr.Zero);
        // this forces a repaint, which for some reason is necessary in some cases.
        this.Invalidate();
    }
John