为什么我的按钮的’Validating’事件处理程序从未调用过?

在下面的迷你应用程序中,我想知道为什么永远不会调用BtnOk_Validating事件处理程序。 我希望单击“确定”按钮可以调用事件处理程序。

真实对话框有更多控件,每个控件都有一个validation事件处理程序。 我的计划是在允许关闭对话框之前使用Ok按钮validation事件处理程序来调用每个其他事件处理程序。

如果不是很明显,那么对于Forms开发来说,我就是新手。

using System.ComponentModel; using System.Windows.Forms; namespace ConsoleApp { class Program { static void Main( string[] args ) { Dialog dialog = new Dialog(); dialog.ShowDialog(); } } public class Dialog : Form { Button m_BtnOk; Button m_BtnCancel; public Dialog() { m_BtnOk = new System.Windows.Forms.Button(); m_BtnCancel = new System.Windows.Forms.Button(); m_BtnOk.CausesValidation = true; m_BtnOk.DialogResult = DialogResult.OK; m_BtnOk.Text = "Ok"; m_BtnOk.Location = new System.Drawing.Point( 0, 0 ); m_BtnOk.Size = new System.Drawing.Size( 70, 23 ); m_BtnOk.Validating += new CancelEventHandler( BtnOk_Validating ); m_BtnCancel.CausesValidation = false; m_BtnCancel.DialogResult = DialogResult.Cancel; m_BtnCancel.Text = "Cancel"; m_BtnCancel.Location = new System.Drawing.Point( 0, 30 ); m_BtnCancel.Size = new System.Drawing.Size( 70, 23 ); Controls.Add( this.m_BtnOk ); Controls.Add( this.m_BtnCancel ); } private void BtnOk_Validating( object sender, CancelEventArgs e ) { System.Diagnostics.Debug.Assert( false ); // we never get here } } } 

编辑:请查看我的后续问题以获得更完整的示例(主要是)。

这是因为按钮永远不会失焦,因为它是唯一的控件。 如果您添加一个TextBox或可以占据按钮焦点的东西,那么您将看到它激发。

来自MSDN

通过使用键盘(TAB,SHIFT + TAB等),通过调用Select或SelectNextControl方法或通过将ContainerControl.ActiveControl属性设置为当前窗体来更改焦点时,焦点事件按以下顺序发生:

  Enter GotFocus Leave Validating Validated LostFocus 

使用鼠标或通过调用Focus方法更改焦点时,焦点事件按以下顺序发生:

  Enter GotFocus LostFocus Leave Validating Validated 

如果CausesValidation属性设置为false,则抑制Validating和Validated事件。

更新:与Hans提到的一样,您需要将所有其他控件的每个Validating事件中的validation提取到单独的函数中。 然后,您可以创建ValidateAll函数来检查所有值。 如果函数返回false ,则不要关闭Form 。 如果返回true ,则调用this.Close() 。 所以它可能看起来像这样:

 // pseudo code textbox1.Validating += ValidateTx1(); textbox2.Validating += ValidateTx2(); btnOk.Click += OkBtnClicked(); private void OkBtnClicked(...) { if(ValidateAll()) { this.Close(); } } private bool ValidateTx1(...) { DoTx1Validation(); } private bool ValidateTx2(...) { DoTx2Validation(); } private bool ValidateAll() { bool is_valid = DoTx1Validation(); return (is_valid && DoTx2Validation()); }