Joseph
Joseph

Reputation: 963

C# Time Delay After User Input

I've got a custom control (inheriting from TextBox) that I'm working with in .NET 4.0.

What I need to be able to do is execute some code after the user has finished his input, e.g. one second after he stops typing.

I can't execute this code block each time the Text changes, for efficiency's sake and because it is somewhat time-consuming. It should ideally only be called once each time the user starts and stops typing. I have begun by using Stopwatch's Restart() inside the OnTextChanged method.

Here's my setup:

public class MyBox : TextBox
{
    private readonly Stopwatch timer;

    protected override void OnTextChanged(TextChangedEventArgs e)
    {
        timer.Restart();

        base.OnTextChanged(e);
    }
}

How can I do this efficiently? Are async threads the answer? Or is there some other way?

Upvotes: 2

Views: 4886

Answers (3)

Johan Larsson
Johan Larsson

Reputation: 17600

Use Binding with Delay. Sample:

<StackPanel>
    <TextBox Text="{Binding ElementName=TextBlock, 
                            Path=Text, 
                            Delay=1000}" />
    <TextBlock x:Name="TextBlock" />
</StackPanel>

Upvotes: 1

Clemens
Clemens

Reputation: 128136

You can easily do the using a DispatcherTimer:

public class MyBox : TextBox
{
    private readonly DispatcherTimer timer;

    public MyBox()
    {
        timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
        timer.Tick += OnTimerTick;
    }

    protected override void OnTextChanged(TextChangedEventArgs e)
    {
        timer.Stop();
        timer.Start();
    }

    private void OnTimerTick(object sender, EventArgs e)
    {
        timer.Stop();
        // do something here
    }
}

Upvotes: 7

Mark A. Donohoe
Mark A. Donohoe

Reputation: 30458

If your code can be run on a separate thread, then design your thread code so that it can be just killed off by killing the thread. Then on every key press, kill the old thread (if it exists) and restart a new one with your code.

Note: if your code needs to interact with the UI thread, then you have to make sure to either invoke back to the main thread, or use the 'UpdateStatus' calls which basically do that for you.

Alternately, your timer method will work, but with the caveat when it executes, the main thread will be locked until it's done, hence my first suggestion of a terminable thread.

Upvotes: 0

Related Questions