不挂其他控件的WinForms验证
本文关键字:WinForms 验证 控件 其他 | 更新日期: 2023-09-27 18:10:39
所以,我在WinForms中遇到了这个问题,至少我认为这是一个问题,我不知道如何解决它。
基本上,当我为控件实现Validating
事件处理程序时,当控件验证失败时,我将CancelEventArgs.Cancel
设置为true。示例代码:
private void NameTextBox_Validating(object sender, CancelEventArgs e) {
// Assume Cool Validation Logic.
//
// ...
var isValid = false;
if (!isValid) {
e.Cancel = true;
// Set an Error Provider Message.
//
// ...
}
}
这会导致整个UI挂起。我不能选择任何其他控件、最小化父窗体窗口或退出父窗体窗口。因此,我发现了一个类似的问题,其答案建议为父窗体实现FormClosing
事件处理程序,并将FormClosingEventArgs.Cancel
设置为false。
问题是,只要我的控件无效,事件处理程序就不会被调用。我有一种感觉,这可能与我的控制层次有关,尽管我不能100%确定。如果有帮助的话,它是:
-- Parent Form
---- Custom User Control
------ Text Box Control (<-- Causes Hang)
我发现了一个非常简单的解决方案,我实际上很沮丧,因为我浪费了这么多时间把头撞在键盘上。
只需将父容器的ContainerControl.AutoValidate
属性设置为EnableAllowFocusChange
,问题就解决了。这里的"父容器"是指实际存放输入控件的容器。
如果你有一个控制层次结构,你也可以将ContainerControl.AutoValidate
属性设置为Inherit
,并简单地将最外层的容器设置为EnableAllowFocusChange
。
希望这对将来的人有所帮助
你可以使用async/await或BackgroundWorker来处理UI线程之外的验证:
// in your init code...
textbox.TextChanged+=(s,e)=>Validate();
// and this is the Validation worker
BackgroundWorker validateWorker = null;
bool isValid = false;
private void Validate(){
if (validateWorker != null){
validateWorker.CancelAsync();
}
isValid = false;
string validateValue = textbox.Text;
BackgroundWorker localCopy = validateWorker = new BackgroundWorker();
validateWorker.WorkerSupportsCancellation = true;
validateWorker.DoWork+=(s,e)=>{
if (CoolValidationAssumed(validateValue) && !localCopy.CancellationPending)
isValid = true;
};
validateWorker.RunWorkerCompleted += (s, e) =>{
if (!localCopy.CancellationPending && !isValid)
textbox.Color = Colors.Red;
}
validationWorker.RunWorkerAsync();
}