Disable Painting of the VScrollbar in a System.Windows.Forms.RichTextBox
I have a custom control inherited from RichTextBox. This control has the ability to "disable" rich text editing. I achive this by just setting the Rtf property to the text property during the TextChanged event.
this is how my code looks like:
private bool lockTextChanged;
void RichTextBox_TextChanged(object sender, EventArgs e)
{
// prevent StackOverflowException
if (lockTextChanged) return;
// remember current position
int rtbstart = rtb.SelectionStart;
int len = rtb.SelectionLength;
// prevent painting
rtb.SuspendLayout();
// set the text property to remove the entire formatting.
lockTextChanged = true;
rtb.Text = rtb.Text;
rtb.Select(rtbstart, len);
lockTextChanged = false;
rtb.ResumeLayout(true);
}
That worked well. However in a large text with like 200 lines the controls jitters (you see the first lines of text for the wink).
To prevent that from happening I filter the WM_PAINT between SuspendLayout() and ResumeLayout()
private bool layoutSuspended;
public new void SuspendLayout()
{
layoutSuspended = true;
base.SuspendLayout();
}
public new void ResumeLayout()
{
layoutSuspended = false;
base.ResumeLayout();
}
public new void ResumeLayout(开发者_如何学JAVAbool performLayout)
{
layoutSuspended = false;
base.ResumeLayout(performLayout);
}
private const int WM_PAINT = 0x000F;
protected override void WndProc(ref System.Windows.Forms.Message m)
{
if (!(m.Msg == WM_PAINT && layoutSuspended))
base.WndProc(ref m);
}
that did the trick, the RichTextBox isn't jittering anymoe.
That's what I wanted to achive, except one thing: The scrollbar is still jittering everytime I type text to my control.Now my question: Does anyone have a clue for me how to prevent the scrollbar from redrawing during Suspend/Resume Layout?
SuspendLayout() isn't going to have an effect, there are no child controls inside an RTB that need to be arranged. RTB is missing the Begin/EndUpdate() methods that most controls have, although it supports it. It suspends painting, although I'm not so sure it suspends updates to the scrollbar. Add them as follows:
public void BeginUpdate() {
SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)0, IntPtr.Zero);
}
public void EndUpdate() {
SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
}
// P/invoke declarations
private const int WM_SETREDRAW = 0xb;
[System.Runtime.InteropServices.DllImport("user32.dll")]
private extern static IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
The better way to prevent the user from editing text is to set the ReadOnly property to True. Removing the scrollbar entirely is possible too by overriding CreateParams.
精彩评论