Click here to Skip to main content
11,648,094 members (69,180 online)
Click here to Skip to main content

Custom TextBox that Delays the TextChanged Event

, 17 Aug 2007 56.5K 2K 26
Rate this:
Please Sign up or sign in to vote.
Textbox that inherits the base textbox control that delays the text changed event

Introduction

Although I've been browsing The Code Project for sometime, this is my first article so take it easy on me!

I was creating another control, a pager control to be exact, and ran into a problem. The problem was that when a user would type in for example 100 to navigate to that page, I was trapping the TextChangedevent and it would first go to page 1, then page 10, then page 100(get the mental picture). I didn't want this to happen for a couple of reasons but the main one is because I'm not storing data of each page in memory and it gets populated when the page is selected from a SQL server, so I wanted to eliminate 3 queries when one is needed for the example previously mentioned.

So I decided that instead of adding a "go" or "refresh" button to my pager control, I would delay the TextBoxTextChangedevent so as long as the user was typing it would not fire the event until he/she was done(delay threshold was met).

Hope it is useful for someone!

Using the Control

Using the control is trivial because there isn't anything different about the TextBoxother than when the TextChangedEvent is fired. The only added property is for the Delay and you would set it like this, assuming you already have the control added to your form.

// Delay in number of milliseconds, the delay gets reset after a key press
// if it hasn't already elapsed
delTextBox1.Delay = 1000;
delTextBox1.TextChanged += new EventHandler(delTextBox1_TextChanged);

Explaining the Source

There are only a few main parts, but could be somewhat confusing for a beginner so I will do my best explaining them.

The first thing to create is a new Control that inherits the base TextBoxcontrol, add the timer, and the Delay property. The timer will be used to control the TextChangedevent that will be discussed later.

...
using System.Timers;

namespace MyControl
{
     public class DelayTextBox : TextBox
     {
           System.Timers.Timer delayTimer;
       private int _threshold = 1000;   // default it 1 second


       // Delay Property to set the amount of time the control
       // waits before firing the TextChanged Event.
           public int Delay
           {
        set{ _threshold = value; }
           }

       public DelayTextBox()
       {
        delayTimer = new System.Timers.Timer( _threshold );
           }
     }
}

The next thing I did was override the KeyPressEvent, I needed this to indicate to the TextChangedevent that something was being typed into the TextBox.

private bool KeysPressed = false;

protected override void OnKeyPress(KeyPressEventArgs e)
{

   // check if timer has been started, if not start
   // if it has, restart it.
   if (!DelayTimer.Enabled)
   {
      DelayTimer.Enabled = true;
   }
   else
   {
      DelayTimer.Enabled = false;
      DelayTimer.Enabled = true;
   }

   // used to indicate the text was changed because a key was pressed
   // and not just setting the text property.
   KeysPressed = true;

   // execute base code as usual
   base.OnKeyPress(e);
}

Now we need to override the TextChangedevent so we can prevent it from firing everytime it actually changes, until the timer elapses.

// set to true in the Timer_Elapsed event.
private bool TimerElapsed = false;

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;  // reset
       KeysPressed = false;   // reset
       base.OnTextChanged(e); // run base TextChanged event code.
   }
}

Finally the code for the Timer_ElapsedEvent. This part was a little more tricky than the rest because the Timerruns in its own thread so using the Invokemethod to make the event fire is required or else it will cause problems in your parent form or control.

public delegate void DelayOverHandler();

public void DelayOver()
{
    // call on textchanged.
    OnTextChanged(new EventArgs());
}

void delayTimer_Elapsed(object sender, EventArgs e)
{
    // stop timer.
    DelayTimer.Enabled = false;

    // set TimerElapsed to true, so the OnTextChange executes its base code.
    TimerElapsed = true;

    // use invoke to get back on the UI thread.
    this.Invoke(new DelayOverHandler(DelayOver), null);
}

This control seems to fit my needs, and I hope someone can use it for something. I plan on adding a keypress filter to only allow numbers, but there are plenty of articles on the topic here to accomplish that.

History

  • 16th August, 2007: Original article posted

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

cdgwinn
Web Developer
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
GeneralMy vote of 5 Pin
Markus Kiss28-Mar-12 3:12
memberMarkus Kiss28-Mar-12 3:12 
QuestionGood article and one question Pin
smatusan1-Dec-08 11:30
membersmatusan1-Dec-08 11:30 
GeneralA Delphi Implementation... Pin
me7me7_19799-Oct-07 3:34
memberme7me7_19799-Oct-07 3:34 
GeneralRe: A Delphi Implementation... Pin
cdgwinn9-Oct-07 5:31
membercdgwinn9-Oct-07 5:31 
GeneralAdditional questions! Pin
Martin#21-Aug-07 5:04
memberMartin#21-Aug-07 5:04 
GeneralRe: Additional questions! Pin
johannesnestler17-Jan-08 5:21
memberjohannesnestler17-Jan-08 5:21 
GeneralKeyPress Filter Pin
Steve Hansen17-Aug-07 5:03
memberSteve Hansen17-Aug-07 5:03 
GeneralRe: KeyPress Filter Pin
cdgwinn17-Aug-07 5:14
membercdgwinn17-Aug-07 5:14 
GeneralRe: KeyPress Filter Pin
Marc Clifton17-Aug-07 15:14
protectorMarc Clifton17-Aug-07 15:14 
GeneralRe: KeyPress Filter Pin
cdgwinn30-Aug-07 4:24
membercdgwinn30-Aug-07 4:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150804.4 | Last Updated 17 Aug 2007
Article Copyright 2007 by cdgwinn
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid