在下面的迷你应用程序中,我想知道为什么永远不会调用BtnOk_Validating事件处理程序。我希望单击“确定”按钮可以调用事件处理程序。
真正的对话框有更多控件,每个控件都有一个验证事件处理程序。我的计划是在允许对话框关闭之前使用Ok按钮验证事件处理程序来调用其他每个事件处理程序。
如果不是很明显,那么在表单开发方面,我就是新手。
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
}
}
}
修改:请参阅我的后续工作question,了解更完整的示例(主要是)。
答案 0 :(得分:6)
因为按钮永远不会失焦,因为它是唯一的控件。如果您添加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事件中的所有其他控件的验证提取到单独的函数中。然后,您可以创建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());
}