using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using System.Timers; /* Except for a couple of minor tweaks, this program came courtesy from the source: * http://www.codeproject.com/KB/miscctrl/CustomTextBox.aspx * author "cdgwinn". (I omitted the Initialize Component()) * to get this working, design your form in Visual Studio as you usually would * within the graphical drag/drop interface. Then go to the actual code of your form ..that * is the .Designmer.cs and look for the textbox in question in the declarations area * (the area where nothing is assigned. Find your textBox and comment away: * private System.Windows.Forms.TextBox myTextBox; * and replace it with: private DelayTextBox myTextBox; * * Then go to the area of the file where everything is instantiated and look for * this.myTextBox = new System.Windows.Forms.TextBox(); * and replace it with: this.myTextBox = new DelayTextBox(); * * Then you can go to your main code for your form and set the keystroke delay * in milliseconds.... * eg: myTextBox.Delay = 50; * * */ namespace TradeIdeas.TIProGUI { public class DelayTextBox : TextBox { private System.Timers.Timer DelayTimer; // used for the delay private bool _timerElapsed = false; // if true OnTextChanged is fired. private bool _keysPressed = false; // makes event fire immediately if it wasn't a keypress private int _delayTime = 1000; // Delay property public int Delay { get { return _delayTime; } set { if (value != _delayTime) { _delayTime = value; DelayTimer.Interval = _delayTime; } } } public DelayTextBox() { DelayTimer = new System.Timers.Timer(_delayTime); DelayTimer.Elapsed += new ElapsedEventHandler(DelayTimer_Elapsed); } void DelayTimer_Elapsed(object sender, ElapsedEventArgs e) { // stop timer. DelayTimer.Enabled = false; // set timer elapsed to true, so the OnTextChange knows to fire _timerElapsed = true; if (InvokeRequired) // InvokeRequired is required! We know that we will be in the wrong thead, // because that's how timers work, so it's tempting to always call Invoke(). // But if you try to call Invoke() after the form has been destroyed, that's // an error. this.Invoke(new DelayOverHandler(DelayOver), null); } protected override void OnKeyPress(KeyPressEventArgs e) { if (!DelayTimer.Enabled) DelayTimer.Enabled = true; else { DelayTimer.Enabled = false; DelayTimer.Enabled = true; } _keysPressed = true; base.OnKeyPress(e); } protected override void OnTextChanged(EventArgs e) { // if the timer elapsed or text was changed by something besides a keystroke // fire base.OnTextChanged if (_timerElapsed || !_keysPressed) { _timerElapsed = false; _keysPressed = false; base.OnTextChanged(e); } } public delegate void DelayOverHandler(); private void DelayOver() { OnTextChanged(new EventArgs()); } } }