C# wait for user to finish typing in a Text Box

I define "finished typing" now as "user has typed something but has not typed anything after a certain time". Having that as a definition i wrote a little class that derives from TextBox to extend it by a DelayedTextChanged event. I do not ensure that is complete and bug free but it satisfied a small smoke test. Feel free to change and/or use it. I called it MyTextBox cause i could not come up with a better name right now. You may use the DelayedTextChangedTimeout property to change the wait timeout. Default is 10000ms (= 10 seconds).

public class MyTextBox : TextBox
{
    private Timer m_delayedTextChangedTimer;

    public event EventHandler DelayedTextChanged;

    public MyTextBox() : base() 
    {
        this.DelayedTextChangedTimeout = 10 * 1000; // 10 seconds
    }

    protected override void Dispose(bool disposing)
    {
        if (m_delayedTextChangedTimer != null)
        {
            m_delayedTextChangedTimer.Stop();
            if (disposing)
                m_delayedTextChangedTimer.Dispose();
        }

        base.Dispose(disposing);            
    }

    public int DelayedTextChangedTimeout { get; set; }

    protected virtual void OnDelayedTextChanged(EventArgs e)
    {
        if (this.DelayedTextChanged != null)
            this.DelayedTextChanged(this, e);
    }

    protected override void OnTextChanged(EventArgs e)
    {
        this.InitializeDelayedTextChangedEvent();
        base.OnTextChanged(e);            
    }                

    private void InitializeDelayedTextChangedEvent()
    {
        if (m_delayedTextChangedTimer != null)
            m_delayedTextChangedTimer.Stop();

        if (m_delayedTextChangedTimer == null || m_delayedTextChangedTimer.Interval != this.DelayedTextChangedTimeout)
        {                
            m_delayedTextChangedTimer = new Timer();
            m_delayedTextChangedTimer.Tick += new EventHandler(HandleDelayedTextChangedTimerTick);
            m_delayedTextChangedTimer.Interval = this.DelayedTextChangedTimeout;
        }

        m_delayedTextChangedTimer.Start();
    }

    private void HandleDelayedTextChangedTimerTick(object sender, EventArgs e)
    {
        Timer timer = sender as Timer;
        timer.Stop();

        this.OnDelayedTextChanged(EventArgs.Empty);
    }
}

Another simple solution would be to add a timer to your form, set the Interval property to 250 and then use the timer's tick event as follows:

private void timer1_Tick(object sender, EventArgs e)
{
    timer1.Stop();
    Calculate(); // method to calculate value
}

private void txtNumber_TextChanged(object sender, EventArgs e)
{
    timer1.Stop();
    timer1.Start();
}

If you are using WPF and .NET 4.5 or later there is a new property on the Binding part of a control named "Delay". It defines a timespan after which the source is updated.

<TextBox Text="{Binding Name, Delay=500}" />

This means the source is updated only after 500 milliseconds. As far as I see it it does the update after typing in the TextBox ended. Btw. this property can be usefull in other scenarios as well, eg. ListBox etc.

Tags:

C#

Textbox