如何跳过在单击“取消”button后进行validation
我使用C#。 我有一个Windows窗体与编辑框和取消button。 编辑框在validation事件中有代码。 每次编辑框失去焦点时,代码都会执行。 当我点击“取消”button时,我只想closures窗体。 我不想要执行编辑框的任何validation。 这怎么能做到呢?
这是一个重要的细节:如果validation失败,那么
e.Cancel = true;
防止离开控制。
但是当用户点击取消button时,表单应该被closures,无论如何。 这怎么能实施?
如果在编辑框失去焦点的时候进行validation,那么取消button就不会停止发生。
但是,如果失败的validation正在阻止取消button的操作,请将该button的CausesValidation
属性设置为false
。
引用: Button.CausesValidation
属性
显然,button的CausesValidation
属性必须设置为false,然后validation事件不会发生在它的点击。 但是,如果button的父控件的CausesValidation
属性设置为true,则可能会失败。 大多数时候,开发人员遗漏/忘记更改容器控件的CausesValidation
属性(如面板控件)。 把这也设为False。 这应该是诀窍。
由于某些控件的validation正在阻止它,所以我的表单closures时遇到了问题。 我已经设置了control.CausesValidation = false
为取消button和取消button的所有父母。 但仍然有问题。
看起来,如果用户正在编辑正在使用validation的字段,并决定放弃(离开字段的input无效),取消button事件被触发,但窗口不会closures。
在取消button点击事件中,这被修改如下:
private void btnCancel_Click(object sender, EventArgs e) { // Stop the validation of any controls so the form can close. AutoValidate = AutoValidate.Disable; Close(); }
将取消button的CausesValidation
属性设置为false
。
将CausesValidation
属性设置为false
。
将原因设置为False是关键,但是这仅仅是不够的。 如果父button的CausesValidation设置为true,则validation事件仍将被调用。 在我的一个案例中,我在表单面板上有一个取消button,所以我必须在面板上设置CausesValidation = false和表单。 最后,我用编程的方式做了这件事,因为它比通过所有的forms更简单。
Control control = cancelButton; while(control != null) { control.CausesValidation = false; control = control.Parent; }
这些答案都没有完成这项工作,但这个线程的最后一个答案是。 基本上,你需要:
- 确保取消button(如果有)具有.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); }
我没有真正回答这个问题,只是指出了实际上做过的两个人。
明智地使用Control.CausesValidation
属性将帮助你实现你想要的。
为了补充Daniel Schaffer的回答:如果在编辑框失去焦点时发生validation,则可以禁止该button激活绕过本地validation并退出。
public class UnselectableButton : Button { public UnselectableButton() { this.SetStyle(ControlStyles.Selectable, false); } }
或者如果你使用DevExpress:
this.simpleButtonCancel.AllowFocus = false;
请注意,这样做会改变键盘的使用体验:选项卡将重点放在取消button上。
也许你想使用BackgroundWorker来延迟一点,所以你可以决定是否validation应该运行。 这里是避免窗体closuresvalidation的例子。
// 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); }
在编辑框的validation码上方添加:
if (btnCancel.focused) { return; }
这应该做到这一点。
在我的情况下,在窗体中我将属性AutoValidate设置为EnableAllowFocusChange
这为我工作。
private void btnCancelar_MouseMove(object sender, MouseEventArgs e) { foreach (Control item in Form.ActiveForm.Controls) { item.CausesValidation = false; } }
- 有两个同名的input元素是有效的吗?
- 我怎样才能添加,删除或交换页面的jQueryvalidation规则?
- 如何将一个RequiredFieldValidator添加到DropDownList控件?
- 用于PHP的最简单的表单validation库?
- Ruby on Rails:errors.add_to_base vs. errors.add
- 如何validation使用ng-repeatdynamic创build的input,ng-show(angular)
- ASP.NET电子邮件validation器正则expression式
- Laravel:Auth :: user() – > id绑定获取一个非对象的属性
- 什么是Rails3版本的errors.add_to_base?