2013-04-23 84 views
2

所以,我在WinForms中遇到了這個問題,至少我認爲它是一個問題,我無法弄清楚如何解決它。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) 

任何想法將不勝感激。

回答

5

我發現了一個解決方案,它是如此簡單,事實上,我不高興我浪費了我的生活如此多小時翻動我的頭靠在鍵盤上。

只需將父容器的ContainerControl.AutoValidate屬性設置爲EnableAllowFocusChange並解決問題即可。本文中的「父容器」表示實際容納輸入控件的容器。

如果您擁有控制層次結構,則還可以將ContainerControl.AutoValidate屬性設置爲Inherit,並將最外層容器設置爲EnableAllowFocusChange

希望這可以幫助未來的人。

-1

您可以使用異步/坐等或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(); 
} 
+0

但不會使'ValidateChildren()'總是返回true嗎? – 9ee1 2013-04-23 21:09:44

+0

@ 9ee1你可以在後臺線程中驗證你喜歡的任何東西,但是你必須首先將所有UI數據複製到模型中,然後驗證模型(或其臨時實例),以便不訪問UI控件 – 2013-04-24 01:02:07

+0

I我不確定這是否會與數據綁定一起工作。另外,如果你查看'ValidateChildren()'的源代碼,順便在UI線程中調用數據綁定的方法,那麼絕對需要實現'Validating'來設置'e.Cancel = true;' 。否則,它會假定你的控件是有效的,如果你使用數據綁定,將允許綁定操作。謝謝你花時間幫忙,你是唯一一個:) – 9ee1 2013-04-24 22:56:21

相關問題