3

所以,我在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)

任何想法将不胜感激。

4

2 回答 2

6

我找到了一个非常简单的解决方案,我真的很沮丧,因为我浪费了这么多小时的时间来敲击键盘。

只需将父容器的ContainerControl.AutoValidate属性设置为即可EnableAllowFocusChange解决问题。在这种情况下,“父容器”是指实际容纳输入控件的容器。

如果您有一个控件层次结构,您还可以将ContainerControl.AutoValidate属性Inherit设置为 并将最外层容器设置为EnableAllowFocusChange

希望这对将来的某人有所帮助。

于 2013-04-24T23:03:03.627 回答
-1

您可以使用 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();
}
于 2013-04-23T21:03:46.047 回答