C# · 12月 26, 2021

c# – 如何在.NET中验证后将焦点设置为控件

我有一个WinForm应用程序,在窗体上有几个输入控件.在验证事件处理程序(验证或验证)中,我需要根据验证的值确定接下来要激活的控件.

在Microsoft的Validating事件文档中,它声明:

Caution

Do not attempt to set focus from within the Enter,GotFocus,Leave,LostFocus,Validating,or Validated event handlers. Doing so can cause your application or the operating system to stop responding. For more information,see the WM_KILLFOCUS topic in the “Keyboard Input Reference” section,and the “Message Deadlocks” section of the “About Messages and Message Queues” topic in the MSDN library at http: // msdn.microsoft.com/library.

Form类有一个ActiveControl属性,允许设置要变为活动的控件,并且不提及任何限制.经过几个小时的网络搜索后,我还没有找到任何其他解决方案.

从我的Validated事件处理程序设置ActiveControl属性(而不是Focus)是一种安全的方式来积极激活我想要的控件吗?如果没有,有什么解决方案吗?

由于.NET Compact Framework没有ActiveControl属性,任何人都可以提出解决方案吗?

解决方法 是的,在验证事件期间更改焦点非常麻烦.事件在焦点变化的确切时间引发.就Windows而言,下一个控件已经获得了焦点,但逻辑形式状态仍然关注于正在验证的控件.将e.Cancel设置为true时,Winforms必须撤消Windows焦点状态.如果不这样做,它必须在事件发生后更新逻辑状态.当你自己改变焦点时,可能会出现各种各样的问题.

重要的是你要等到焦点被整理出来.最好的办法是延迟代码,直到所有内容都运行完毕并且表单再次处于空闲状态.您可以使用Control.BeginInvoke()方法干净地执行此操作.像这样的东西:

private delegate void ChangeFocusDelegate(Control ctl); private void text@R_798_2419@1_Validating(object sender,CancelEventArgs e) { int value; if (!int.TryParse(text@R_798_2419@1.Text,out value)) e.Cancel = true; else { if (value == 1) this.BeginInvoke(new ChangeFocusDelegate(changeFocus),text@R_798_2419@2); else this.BeginInvoke(new ChangeFocusDelegate(changeFocus),text@R_798_2419@3); } } private void changeFocus(Control ctl) { ctl.Focus(); }