2010-03-23 173 views
54

我有一個對話框,我用<class>.ShowDialog()顯示。它有一個確定按鈕和一個取消按鈕;確定按鈕也有一個事件處理程序。防止在按鈕的單擊事件處理程序中關閉對話框

我想在事件處理程序中進行一些輸入驗證,如果失敗,請通過消息框通知用戶並阻止對話框關閉。我不知道如何做最後一部分(防止關閉)。

回答

38

既然你已經指定你想有一個彈出錯誤對話框,這樣做的一個方法是將驗證移動到OnClosing事件處理程序。在這個例子中,如果用戶對對話框中的問題回答「是」,那麼窗體關閉就會中止。

private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e) 
{ 
    // Determine if text has changed in the textbox by comparing to original text. 
    if (textBox1.Text != strMyOriginalText) 
    { 
     // Display a MsgBox asking the user to save changes or abort. 
     if(MessageBox.Show("Do you want to save changes to your text?", "My Application", 
     MessageBoxButtons.YesNo) == DialogResult.Yes) 
     { 
     // Cancel the Closing event from closing the form. 
     e.Cancel = true; 
     // Call method to save file... 
     } 
    } 
} 

通過設置e.Cancel = true您將阻止表單關閉。

然而,這將是一個更好的設計/用戶體驗內嵌顯示驗證錯誤(通過突出以某種方式違規的領域,顯示工具提示等)並防止用戶選擇的確定按鈕第一個地方。

+4

這會工作......但會是糟糕的UI練習。 OP已經顯示了一個對話框,然後拋出其他!更好地使用現有的Winform驗證技術禁用「確定」按鈕 – Adrian 2010-03-23 12:22:54

+2

@Adrian - 我確實說過「單向」;)。這完全取決於錯誤發生的可能性和/或嚴重程度。在做出最終決定之前,我需要查看錶單的設計。 – ChrisF 2010-03-23 12:26:54

+0

同意了,我剛剛讀過OP,看到他確實想要一個HORRIBLE對話框彈出! – Adrian 2010-03-23 12:31:13

0

您可以在用戶點擊確定按鈕之前檢查表單。如果這不是一個選項,那麼打開一個消息框表示出現錯誤,並重新打開之前狀態的表單。

+0

你也許可以檢查表單的用戶點擊確定按鈕前 - >什麼時候?我只能在他們嘗試「提交」(借用網絡術語)時才能檢查它,否則將僅僅因爲用戶沒有機會首先填寫它而無效。你的第二個建議很難實現;我希望做些簡單的事情(或者採取不同的方式來做我想做的事情) – qster 2010-03-23 12:08:22

2

你可以捕捉FormClosing那裏的強制形式保持打開狀態。 使用該事件參數對象的Cancel屬性。

e.Cancel = true; 

它應該停止您的表單關閉。

4

這並不直接回答你的問題(其他人已經有了),但從可用性的角度來看,我寧願在輸入無效時禁用違規按鈕。

+0

嗯,是的,我想到了這一點,但是當一個特定的輸入包含一個無效值時,它顯然標有紅色背景..我認爲即使禁用該按鈕對於實現微不足道,我猜也沒有缺陷。它 – qster 2010-03-23 12:20:42

+0

這種方法的問題是,對於更復雜的表單,用戶可能不明白他們需要做什麼才能再次啓用按鈕。這種動態驗證可以更好地與其他事物結合使用,例如ErrorProviders等。 – dreamlax 2013-07-25 11:32:45

12

不要使用此事件的FormClosing,你要允許用戶擯棄取消或者單擊X簡單實現OK按鈕的Click事件處理程序和Don」對話框t關閉直到你快樂:

private void btnOk_Click(object sender, EventArgs e) { 
    if (ValidateControls()) 
    this.DialogResult = DialogResult.OK; 
} 

其中「ValidateControls」是您的驗證邏輯。如果出現錯誤,請返回false。

+0

一個小細節 - 假設您沒有指定DialogResult:OK作爲OK的設計時設置的一部分按鈕。 – RenniePet 2013-03-27 04:06:44

+1

然後你做相反的事,當驗證失敗時將它設置爲None。 – 2013-03-27 04:10:08

3

使用此代碼:

private void btnOk_Click(object sender, EventArgs e) { 
    if (ValidateControls()) 
    this.DialogResult = DialogResult.OK; 
} 

的它的問題是,用戶必須CLIC兩次按鈕用於封閉形式;

121

您可以通過將表格的DialogResult設置爲DialogResult.None來取消關閉。

一個實例,其中按鈕1是的AcceptButton:

private void button1_Click(object sender, EventArgs e) { 
    if (!validate()) 
    this.DialogResult = DialogResult.None; 
} 

當用戶點擊按鈕1和驗證方法返回false,形式不會被關閉。

+0

那麼是否還需要添加'else DialogResult = DialogResult.OK',以便在修復錯誤並在下一次正確設置對話框結果時點擊OK? – krillgar 2013-07-16 13:54:13

+1

因爲AcceptButton是button1,所以在單擊時,DialogResult始終設置爲DialogResult.OK。 – Arjan 2013-07-23 08:31:58

+1

哦對。這實際上並不會覆蓋該按鈕的DialogResult,只是將其更改爲該邏輯的該分支。 – krillgar 2013-07-23 10:44:41

0

只需添加一行事件功能

private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) 
      { 
       this->DialogResult = System::Windows::Forms::DialogResult::None; 
      } 
0
void SaveInfo() 
{ 
blnCanCloseForm = false; 
Vosol[] vs = getAdd2DBVosol(); 
if (DGError.RowCount > 0) 
return; 

Thread myThread = new Thread(() => 
{ 
this.Invoke((MethodInvoker)delegate { 
    picLoad.Visible = true; 
    lblProcces.Text = "Saving ..."; 
}); 
int intError = setAdd2DBVsosol(vs); 
Action action = (() => 
{ 
    if (intError > 0) 
    { 
     objVosolError = objVosolError.Where(c => c != null).ToArray(); 
     DGError.DataSource = objVosolError;// dtErrorDup.DefaultView; 
     DGError.Refresh(); 
     DGError.Show(); 
     lblMSG.Text = "Check Errors..."; 
    } 
    else 
    { 
     MessageBox.Show("Saved All Records..."); 
     blnCanCloseForm = true; 
     this.DialogResult = DialogResult.OK; 
     this.Close(); 
    } 

}); 
this.Invoke((MethodInvoker)delegate { 
    picLoad.Visible = false; 
    lblProcces.Text = ""; 
}); 
this.BeginInvoke(action); 
}); 
myThread.Start(); 
} 

void frmExcellImportInfo_FormClosing(object s, FormClosingEventArgs e) 
{ 
    if (!blnCanCloseForm) 
     e.Cancel = true; 
} 
相關問題