Creating a flicker-free text box that can be rapidly updated
I'm trying to create a search tool and would like to display the res开发者_Go百科ults in a text box, much like the one contained in Visual Studio - this means that for long searches results will be appended to the end of the text box while the user is attempting to look at the results at the top of the text box.
At the moment I'm using a standard textbox, however it has many problems:
- The text box flickers madly while the search is in progress
- Its not possible for the user to scroll while results are being appended to the box
- Its not possible for the user to copy and paste results in the text box while results are being appended.
Are there any ways of working around these issues, or should I look into using another control / creating my own?
Microsoft forgot to implement the Begin/EndUpdate() methods for TextBox. You can add them yourself, it solves the problem. You can't get rid of the flicker though. Sample code:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
timer1.Interval = 10;
timer1.Tick += new EventHandler(timer1_Tick);
button1.Click += new EventHandler(button1_Click);
}
void timer1_Tick(object sender, EventArgs e) {
int pos = textBox1.SelectionStart;
int len = textBox1.SelectionLength;
SendMessage(textBox1.Handle, 11, IntPtr.Zero, IntPtr.Zero);
textBox1.AppendText(DateTime.Now.ToString() + Environment.NewLine);
SendMessage(textBox1.Handle, 11, (IntPtr)1, IntPtr.Zero);
//if (textBox1 is RichTextBox) textBox1.Invalidate();
textBox1.SelectionStart = pos;
textBox1.SelectionLength = len;
}
private void button1_Click(object sender, EventArgs e) {
timer1.Enabled = !timer1.Enabled;
}
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
}
}
At first to access your TextBox while your search is running you should put your search into a BackgroundWorker
and put the (intermediate) results with BeginInvoke()
into your TextBox. So your GUI doesn't hang while your search is running.
Also you should use the TextBox.AppendText()
method to add the text to your box. And if you want an auto-scroll use the two liner below after AppendText:
textBoxMessages.SelectionStart = textBoxMessages.Text.Length;
textBoxMessages.ScrollToCaret();
And if you want to enable/disable autoscroll you can before AppendText check if SelectionStart is equal to Text.Lenght and only if this is true make the above two liner after AppendText
Update
Ok, to get rid of that flickering there is no real solution within the textbox. When i mentioned right, you can give the RichTextBox a try, because it performs better with these scrolling problems.
Last but not least you can use ScintillaNET. I used it already several times and for these purposes it solves all the problems.
The only thing you can't do elegant by ScintillaNet (or better with Scintilla) is colorize manually a custom section. You have always to use a lexer which works with pre-defined formatting on a list of keywords.
Textboxes are good for editable content -- are the search results editable?
If you're displaying results to a search, why don't you use a DataGrid? You can design it to look however you want (it can look like a textbox with rows & rows of text)
精彩评论