G
Guest
I have created a Control that extends RichTextBox to do syntax-hilighting. My
strategy is to have a timer that restarts every time a user types a key so
that it can wait until the user pauses for at least 500 milliseconds, then
perform its work. The hilighting simply goes through a list of keywords,
finding each instance in the RichTextBox, and selecting it in order to change
its color. I figured out how to remember where the cursor is and put it back
where the user left it. I even bracketed all my activity with a
SuspendLayout/ResumeLayout. But I cannot get around my problem: the RTB has
an annoying flash/scroll/jump each time my hilighting occurs (if there are
more lines in the box than the height of the box). How can I avoid this?
Here is the code basics:
==================================
private void SyntaxHilightTextBox_TextChanged(object sender, EventArgs e)
{
if (timer.Tag.Equals(1)) { return; }
if (timer.Enabled) { timer.Stop(); }
timer.Start(); // restart it
}
private void timer_Tick(object sender, EventArgs e)
{
timer.Stop();
timer.Tag = 1; // disable TextChanged so our changes are transparent
SuspendLayout();
Colorize();
ResumeLayout();
timer.Tag = 0; // re-enable TextChanged
}
private void Colorize()
{
int saveCaret = CaretPosition();
// Restore all text to black.
// Prevents terminal hilighting from bleeding into new typing.
SelectAll();
SelectionColor = Color.Black;
ColorWords(myWordList);
SelectionStart = saveCaret; // restore caret
SelectionLength = 0;
}
public void ColorWords(string[] text)
{
foreach (string s in text) { ColorWord(s); }
}
public void ColorWord(string text)
{
RichTextBoxFinds options =
(RichTextBoxFinds.WholeWord | RichTextBoxFinds.NoHighlight);
int start = Find(text, options);
bool done = (start < 0);
while (!done)
{
SelectionStart = start;
SelectionLength = text.Length;
SelectionColor = hilightColor;
int lastStart = start;
start = Find(text, start + text.Length, options);
done = (start <= lastStart);
}
}
==================================
strategy is to have a timer that restarts every time a user types a key so
that it can wait until the user pauses for at least 500 milliseconds, then
perform its work. The hilighting simply goes through a list of keywords,
finding each instance in the RichTextBox, and selecting it in order to change
its color. I figured out how to remember where the cursor is and put it back
where the user left it. I even bracketed all my activity with a
SuspendLayout/ResumeLayout. But I cannot get around my problem: the RTB has
an annoying flash/scroll/jump each time my hilighting occurs (if there are
more lines in the box than the height of the box). How can I avoid this?
Here is the code basics:
==================================
private void SyntaxHilightTextBox_TextChanged(object sender, EventArgs e)
{
if (timer.Tag.Equals(1)) { return; }
if (timer.Enabled) { timer.Stop(); }
timer.Start(); // restart it
}
private void timer_Tick(object sender, EventArgs e)
{
timer.Stop();
timer.Tag = 1; // disable TextChanged so our changes are transparent
SuspendLayout();
Colorize();
ResumeLayout();
timer.Tag = 0; // re-enable TextChanged
}
private void Colorize()
{
int saveCaret = CaretPosition();
// Restore all text to black.
// Prevents terminal hilighting from bleeding into new typing.
SelectAll();
SelectionColor = Color.Black;
ColorWords(myWordList);
SelectionStart = saveCaret; // restore caret
SelectionLength = 0;
}
public void ColorWords(string[] text)
{
foreach (string s in text) { ColorWord(s); }
}
public void ColorWord(string text)
{
RichTextBoxFinds options =
(RichTextBoxFinds.WholeWord | RichTextBoxFinds.NoHighlight);
int start = Find(text, options);
bool done = (start < 0);
while (!done)
{
SelectionStart = start;
SelectionLength = text.Length;
SelectionColor = hilightColor;
int lastStart = start;
start = Find(text, start + text.Length, options);
done = (start <= lastStart);
}
}
==================================