我使用 C#。我有一个带有编辑框和取消按钮的 Windows 窗体。编辑框有验证事件的代码。每次编辑框失去焦点时都会执行代码。当我单击取消按钮时,我只想关闭表单。我不希望对要执行的编辑框进行任何验证。如何实现?
这是一个重要的细节:如果验证失败,那么
e.Cancel = true;
防止离开控件。
但是当用户单击取消按钮时,无论如何都应该关闭表单。如何实施?
我使用 C#。我有一个带有编辑框和取消按钮的 Windows 窗体。编辑框有验证事件的代码。每次编辑框失去焦点时都会执行代码。当我单击取消按钮时,我只想关闭表单。我不希望对要执行的编辑框进行任何验证。如何实现?
这是一个重要的细节:如果验证失败,那么
e.Cancel = true;
防止离开控件。
但是当用户单击取消按钮时,无论如何都应该关闭表单。如何实施?
如果在编辑框失去焦点时发生验证,那么取消按钮不会阻止这种情况的发生。
但是,如果失败的验证阻止取消按钮执行其操作,请将CausesValidation
按钮的属性设置为false
.
显然CausesValidation
,按钮的属性必须设置为 false,然后验证事件将永远不会在其单击时发生。但是,如果按钮的父控件将其CausesValidation
属性设置为 true,则此操作可能会失败。大多数情况下,开发人员会错过/忘记更改CausesValidation
容器控件(如面板控件)的属性。也将其设置为 False。这应该可以解决问题。
我在关闭表单时遇到问题,因为某些控件的验证正在停止它。我已经control.CausesValidation = false
为取消按钮和取消按钮的所有父项设置了。但是还是有问题。
似乎如果用户正在编辑正在使用验证的字段并决定放弃(留下无效输入的字段),则取消按钮事件被触发但窗口不会关闭。
取消按钮单击事件中的以下内容已解决此问题:
private void btnCancel_Click(object sender, EventArgs e)
{
// Stop the validation of any controls so the form can close.
AutoValidate = AutoValidate.Disable;
Close();
}
将CausesValidation
取消按钮的属性设置为false
。
将CausesValidation
属性设置为false
。
这些答案都没有完成这项工作,但这个线程的最后一个答案确实如此。基本上,您需要:
覆盖此虚拟方法。
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);
}
我并没有真正回答这个问题,只是指着实际回答的两个人。
就我而言,在表单中我将属性AutoValidate设置为EnableAllowFocusChange
明智地使用该Control.CausesValidation
物业将帮助您实现您想要的。
将 CausesValidation 设置为 false 是关键,但是仅此还不够。如果按钮父级将 CausesValidation 设置为 true,则仍将调用验证事件。在我的一个案例中,我在表单的面板上有一个取消按钮,所以我必须在面板和表单上设置 CausesValidation = false。最后我以编程方式完成了这项工作,因为它比浏览所有表格更简单......
Control control = cancelButton;
while(control != null)
{
control.CausesValidation = false;
control = control.Parent;
}
在编辑框的验证码上方添加:
if (btnCancel.focused)
{
return;
}
那应该这样做。
作为对 Daniel Schaffer 回答的补充:如果在编辑框失去焦点时发生验证,您可以禁止按钮激活以绕过本地验证并退出。
public class UnselectableButton : Button
{
public UnselectableButton()
{
this.SetStyle(ControlStyles.Selectable, false);
}
}
或者如果你使用 DevExpress:
this.simpleButtonCancel.AllowFocus = false;
请注意,这样做会改变键盘体验:选项卡将不再关注取消按钮。
也许您想使用 BackgroundWorker 稍微延迟,这样您就可以决定是否应该运行验证。这是在表单关闭时避免验证的示例。
// The flag
private bool _isClosing = false;
// Action that avoids validation
protected override void OnClosing(CancelEventArgs e) {
_isClosing = true;
base.OnClosing(e);
}
// Validated event handler
private void txtControlToValidate_Validated(object sender, EventArgs e) {
_isClosing = false;
var worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerAsync();
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
}
// Do validation on complete so you'll remain on same thread
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
if (!_isClosing)
DoValidationHere();
}
// Give a delay, I'm not sure this is necessary cause I tried to remove the Thread.Sleep and it was still working fine.
void worker_DoWork(object sender, DoWorkEventArgs e) {
Thread.Sleep(100);
}
我今天在调查发生验证错误时为什么我的表单不会关闭时发现了这个线程。
我尝试了CausesValidation = false
关闭按钮和表单本身(X 关闭)。
这种复杂的形式没有任何效果。
在阅读评论时,我发现了一个看起来很完美的评论
在表单关闭事件上,而不是关闭按钮(所以它也会在单击 X 时触发)
这成功了。
AutoValidate = AutoValidate.Disable;
创建一个布尔值:
bool doOnce;
在您的函数中将其设置为 false ,然后:
if (doOnce == false)
{
e.cancel = true;
doOnce = true;
}
这意味着它只会运行一次,您应该可以取消它。无论如何,这对我有用。
这是一个老问题,但是我最近遇到了这个问题并以这种方式解决了它:
第一,我们将一个UserControl加载到一个具有保存和取消按钮的“shell”表单中。UserControl继承了一个接口(如IEditView ),该接口具有Save、Cancel、Validate和ToggleValidate的功能。
在 shell 表单中,我们使用鼠标进入和鼠标离开,如下所示:
private void utbCancel_MouseEnter(object sender, EventArgs e)
{
((Interface.IEdit)tlpMain.Controls[1]).ToggleValidate();
}
private void utbCancel_MouseLeave(object sender, EventArgs e)
{
((Interface.IEdit)tlpMain.Controls[1]).ToggleValidate();
}
然后在 ToggleValidate 中(比如说一个带有两个控件的简单表单......如果你愿意,你可以随时遍历一个列表)我们设置 CausesValidation
public bool ToggleValidate()
{
uneCalcValue.CausesValidation = !uneCalcValue.CausesValidation;
txtDescription.CausesValidation = !txtDescription.CausesValidation;
return txtDescription.CausesValidation;
}
希望这可以帮助。
这对我有用。
private void btnCancelar_MouseMove(object sender, MouseEventArgs e)
{
foreach (Control item in Form.ActiveForm.Controls)
{
item.CausesValidation = false;
}
}