大家好,
有没有一种内置的方法可以知道用户何时完成了在文本框中的键入?(在按tab键或移动鼠标之前)我有一个数据库查询,该查询发生在textchanged事件上,一切都运行得很好。然而,我注意到当然有一点滞后,因为如果用户在文本框中快速输入,程序就会忙于查询每个字符。所以我希望的是一种查看用户是否已经完成输入的方法。因此,如果他们输入"a“并停止,则会触发一个事件。但是,如果他们输入"all the way“,事件会在y键之后触发。
我有一些想法在我的脑海中浮现,但我确信它们不是最有效的。比如测量自上一次textchange事件以来的时间,如果它大于某个值,那么它将继续运行我的其余过程。
让我知道你的想法。
语言: VB.NET框架:.Net 2.0
--编辑以澄清“完成键入”
发布于 2010-05-06 06:51:28
对于那些在.NET 2.0中需要类似东西的人,我在这里制作了一个派生自TextBox并使用相同方法的控件。希望这对你有所帮助
public partial class TextBox : System.Windows.Forms.TextBox
{
private ManualResetEvent _delayMSE;
public event EventHandler OnUserStopTyping;
private delegate bool TestTimeout();
public TextBox()
{
_delayMSE = new ManualResetEvent(false);
this.TextChanged += new EventHandler(TextBox_TextChanged);
}
void TextBox_TextChanged(object sender, EventArgs e)
{
_delayMSE.Set();
Thread.Sleep(20);
_delayMSE.Reset();
TestTimeout tester = new TestTimeout(TBDelay);
tester.BeginInvoke(new AsyncCallback(Test), tester);
}
private void Test(IAsyncResult pResult)
{
bool timedOut = (bool)((TestTimeout)pResult.AsyncState).EndInvoke(pResult);
if (timedOut)
{
if (OnUserStopTyping != null)
OnUserStopTyping(this, null);
}
}
private bool TBDelay()
{
return !_delayMSE.WaitOne(500, false);
}
}
发布于 2009-07-23 16:07:29
我最终尝试了Scott Weinstein answer,尽管它需要一些关于线程、委托和基本lambda语法的更深层次的知识。而且它工作得很好。他最初的回答并不是纯粹的复制-粘贴,所以我不得不做一些工作来让它工作。
我在Thread.Sleep中增加了很少的时间,因为我注意到,如果用户输入非常快,但在一些按键之间有很小的随机延迟,则invoke方法可能会发生两次。您还必须添加对WindowsBase程序集的引用才能使用Dispatcher。
我用1.5秒等待用户结束输入。
// use manual reset event to Q up waiting threads.
// each new text changed event clears the Q
// only the last changed will hit the timeout, triggering the action
private ManualResetEvent _delayMSE;
private Func<bool> TBDelay;
private delegate void ActionToRunWhenUserStopstyping();
public Form1()
{
InitializeComponent();
_delayMSE = new ManualResetEvent(false);
TBDelay = () => !_delayMSE.WaitOne(1500, false);
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
_delayMSE.Set();
// open the ResetEvent gate, to discard these delays
Thread.Sleep(20);
// let all pending through the gate
_delayMSE.Reset();
// close the gate
TBDelay.BeginInvoke(res =>
{
// callback code
// check how we exited, via timeout or signal.
bool timedOut = TBDelay.EndInvoke(res);
if (timedOut)
Dispatcher.CurrentDispatcher.Invoke(
new ActionToRunWhenUserStopstyping(DoWhatEverYouNeed),
DispatcherPriority.Input);
}, null);
}
private void DoWhatEverYouNeed()
{
MessageBox.Show(textBox1.Text);
}
发布于 2009-03-22 22:43:40
这取决于你所说的“完成输入”是什么意思。有一个事件可以让您知道用户何时离开了该特定控件的焦点。此外,还有一个changed even,它会在文本发生变化时告诉你。你可以做的是捕获两件事:
1)失去焦点
2)每次用户更改文本时,启动计时器,例如,20秒,如果用户在该时间内完成,则用户“完成”打字。也就是说,如果用户在该时间内没有做任何事情,那么就假设用户“完成”了。
如果这两件事中的任何一件发生,那么用户就完成了,请确保适当地停止并重新启动计时器。显然,您可以更改超时。
这完全取决于你想如何定义它。
https://stackoverflow.com/questions/671728
复制相似问题