I've got a custom control (inheriting from TextBox) that I'm working with in .NET 4.0.
我在。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.
我不能在每次文本更改时执行这个代码块,这是为了提高效率,而且有点浪费时间。理想情况下,每次用户启动和停止键入时,应该只调用一次。我已经开始在OnTextChanged方法中使用Stopwatch的Restart()。
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?
我怎样才能有效地做到这一点呢?异步线程是答案吗?还是有别的办法?
3 个解决方案
#1
6
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
}
}
#2
1
Use Binding with Delay. Sample:
用延迟绑定。示例:
<StackPanel>
<TextBox Text="{Binding ElementName=TextBlock,
Path=Text,
Delay=1000}" />
<TextBlock x:Name="TextBlock" />
</StackPanel>
#3
0
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.
注意:如果您的代码需要与UI线程交互,那么您必须确保调用回主线程,或者使用“UpdateStatus”调用,这基本上是为您做的。
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.
或者,您的计时器方法可以工作,但是在执行时需要注意,主线程将被锁定,直到完成,因此我第一次建议使用可终止的线程。
#1
6
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
}
}
#2
1
Use Binding with Delay. Sample:
用延迟绑定。示例:
<StackPanel>
<TextBox Text="{Binding ElementName=TextBlock,
Path=Text,
Delay=1000}" />
<TextBlock x:Name="TextBlock" />
</StackPanel>
#3
0
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.
注意:如果您的代码需要与UI线程交互,那么您必须确保调用回主线程,或者使用“UpdateStatus”调用,这基本上是为您做的。
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.
或者,您的计时器方法可以工作,但是在执行时需要注意,主线程将被锁定,直到完成,因此我第一次建议使用可终止的线程。