2010-03-23 94 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; 
} 
相关问题