Roman Nazarkin
Roman Nazarkin

Reputation: 2229

Real-Time Text Processing

I have a program, that translates text into another language. I want to improve it with this small feature: text translates in real time when user types it.

I have written this code:

private void TextBox_KeyUp_1(object sender, System.Windows.Input.KeyEventArgs e)
{
   TranslateBox.Text = translate.translateText(TextToTranslate.Text, "eng", "es");
}

It works, but while I type "Hello World", this function will be called 11 times. It's a big load. Is there any way to set the timeout for this function?

PS. I know how it does in JS, but not in C#...

Upvotes: 2

Views: 717

Answers (3)

David
David

Reputation: 16277

You can also consider do the actual translation when you found a "word" is finished, such as after a space/tab/enter key is typed, or when the textbox losts focus etc.

private void TextBox_KeyUp_1(object sender, System.Windows.Input.KeyEventArgs e)
{
   if(...) // Here fill in your condition
      TranslateBox.Text = translate.translateText(TextToTranslate.Text, "eng", "es");
}

Upvotes: 3

tukaef
tukaef

Reputation: 9214

You can use delayed binding:

<TextBox Text="{Binding Path=Text, Delay=500, Mode=TwoWay}"/>

Note that you should set some class that has property called Text and implements INotifyPropertyChanged as DataContext of the Window or UserControl or TextBox itself.

Example at msdn: http://msdn.microsoft.com/en-us/library/ms229614.aspx

Upvotes: 0

Fredrik M&#246;rk
Fredrik M&#246;rk

Reputation: 158369

I have used the following code for similar purposes:

private readonly ConcurrentDictionary<string, Timer> _delayedActionTimers = new ConcurrentDictionary<string, Timer>();
private static readonly TimeSpan _noPeriodicSignaling = TimeSpan.FromMilliseconds(-1);

public void DelayedAction(Action delayedAction, string key, TimeSpan actionDelayTime)
{
    Func<Action, Timer> timerFactory = action =>
        {
            var timer = new Timer(state =>
                {
                    var t = state as Timer;
                    if (t != null) t.Dispose();
                    action();
                });
            timer.Change(actionDelayTime, _noPeriodicSignaling);
            return timer;
        };

    _delayedActionTimers.AddOrUpdate(key, s => timerFactory(delayedAction),
        (s, timer) =>
            {
                timer.Dispose();
                return timerFactory(delayedAction);
            });
}

In your case, you could use it like this:

DelayedAction(() => 
    SetText(translate.translateText(TextToTranslate.Text, "eng", "es")), 
    "Translate", 
    TimeSpan.FromMilliseconds(250));

...where the SetText method would assign the string to the textbox (using the appropriate dispatcher for thread synchronization).

Upvotes: 0

Related Questions