问题描述:
当光标聚焦在一个表单的提交按钮上,用户按回车,程序会访问服务器进行数据保存,此时会阻塞UI线程。如果此时用户继续拼命按回车,这些事件会堆积在那里,待服务器返回结果后,UI线程会接收到这些堆积的回车事件,继续触发提交操作
解决思路:
-
将保存方法改成异步,不再阻塞UI线程,并在用户按下回车后,将控件离焦。待方法执行完成,再将控件重新聚焦
-
不使用异步,同样需要在用户按下回车后,将控件离焦,待方法执行完成,再将控件重新聚焦,但要注意一点,重新聚焦前要让UI线程有喘息的时间来处理掉堆积的事件,否则这些事件依然会在控件重新聚焦后落到控件上
方案1同步改异步,交互方案、代码结构要做调整,方案2调整较小,但要注意给UI线程留喘息的时间
以下代码以文本框控件示例
/// <summary>
/// Txt1键盘事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Txt1_KeyDown(object sender, KeyEventArgs e)
{
//离焦
Txt3.Focus();
//业务处理
Thread.Sleep(500);
if (e.Key == Key.Enter)
{
Txt1.Text = Txt1.Text + "1";
}
//聚焦回来
Task.Factory.StartNew(() =>
{
Thread.Sleep(100);//等待一段时间,让UI线程处理掉堆积的回车事件
//线程内操作UI线程的控件要使用Dispatcher
Dispatcher.BeginInvoke(new Action(() => {
Txt1.Focus();
}));
});
}