Dav*_* R. 13 .net c# validation winforms
我有一个带有单个TextBox的简单表单,以及OK和Cancel按钮.Form的AcceptButton和CancelButton设置正确,OK和Cancel按钮的DialogResult设置为'OK'和'Cancel'.
我想在TextBox中添加验证,这将阻止用户在验证失败时对表单进行确认,但这也将允许它们像往常一样取消.
默认情况下,在所有控件上,CausesValidation属性为True,但我在取消按钮上将其更改为False.
果然,单击"确定"或按Enter键将运行我连接到TextBox的验证事件.按取消按钮绕过验证,这是完美的.
然而,按Escape取消形式并没有执行一样按下取消按钮-它引发Validating事件,并防止使用者从离开.
是否有任何方法可以使Escape键按预期执行,即不提高Validating事件,就像按下取消按钮一样?
一个完整的解决方案是:
创建一个新的Windows窗体应用程序.将第二个表单添加到项目中.
在InitializeComponent()之后将此代码粘贴到Form1的构造函数中:
MessageBox.Show((new Form2()).ShowDialog().ToString());
Run Code Online (Sandbox Code Playgroud)
这显示了从我们的第二个表单传回的DialogResult.
在InitializeComponent()之后将此代码粘贴到Form2的构造函数中:
TextBox txtName = new TextBox();
txtName.Validating +=
new CancelEventHandler((sender, e) =>
{
if (txtName.Text.Length == 3)
{
MessageBox.Show("Validation failed.");
e.Cancel = true;
}
});
Button btnOk = new Button
{
Text = "OK",
DialogResult = DialogResult.OK
};
Button btnCancel = new Button
{
Text = "Cancel",
CausesValidation = false,
DialogResult = DialogResult.Cancel
};
FlowLayoutPanel panel = new FlowLayoutPanel();
panel.Controls.AddRange(new Control[]
{
txtName, btnOk, btnCancel
});
this.AcceptButton = btnOk;
this.CancelButton = btnCancel;
this.Controls.Add(panel);
Run Code Online (Sandbox Code Playgroud)
在这个简化的示例中,如果输入了3个字符,则文本框将不允许您继续.即使有3个字符,您也可以直接按取消按钮或关闭表格; 但是按下Escape键不会这样做 - 它会触发Validating事件,而它应该与按Cancel取消相同.
Han*_*ant 16
是的,这是ValidateChildren方法的一个尴尬的怪癖.它不知道取消是有意的.粘贴此代码以解决问题:
protected override void OnFormClosing(FormClosingEventArgs e) {
base.OnFormClosing(e);
e.Cancel = false;
}
Run Code Online (Sandbox Code Playgroud)
要避免运行导致副作用的Validate事件处理程序(如消息框),请将此语句添加到方法的顶部:
private void txtName_Validating(object sender, CancelEventArgs e)
{
if (this.DialogResult != DialogResult.None) return;
// etc..
}
Run Code Online (Sandbox Code Playgroud)
将此代码粘贴到表单中以在尝试验证表单之前设置DialogResult:
protected override bool ProcessDialogKey(Keys keyData) {
if (keyData == Keys.Escape) this.DialogResult = DialogResult.Cancel;
return base.ProcessDialogKey(keyData);
}
Run Code Online (Sandbox Code Playgroud)
我刚看到这个问题,因为我正在寻找相同的解决方案,并且ProcessdialogKey的覆盖是MS批准的解决方案,直到他们修复了错误(Escape应该像单击取消一样).此处也可以找到对此错误的讨论(仅使用Visual Basic而不是C#.错误已超过5年,显然仍未修复):错误还是功能?CancelButton vs Escape Key我正在尝试解决C++解决方案.
编辑添加:来自C#链接的解决方案:
protected override bool ProcessDialogKey(Keys keyData)
{
if (keyData == Keys.Escape)
{
this.AutoValidate = AutoValidate.Disable;
cancelButton.PerformClick();
this.AutoValidate = AutoValidate.Inherit;
return true;
}
return base.ProcessDialogKey(keyData);
}
Run Code Online (Sandbox Code Playgroud)