防止对话框在按钮的单击事件处理程序中关闭

问题描述 投票:0回答:11

我有一个用

<class>.ShowDialog()
显示的对话框。它有一个确定按钮和一个取消按钮; OK 按钮还有一个事件处理程序。

我想在事件处理程序中进行一些输入验证,如果失败,则用消息框通知用户并阻止对话框关闭。我不知道如何做最后一部分(防止关闭)。

c# .net windows winforms
11个回答
162
投票

您可以通过将表单的

DialogResult
设置为
DialogResult.None
来取消关闭。

button1 是 AcceptButton 的示例:

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

当用户点击button1并且validate方法返回false时,表单不会关闭。


55
投票

鉴于您已指定想要弹出错误对话框,执行此操作的一种方法是将验证移至

Form.OnFormClosing
事件处理程序。在此示例中,如果用户对对话框中的问题回答“是”,则表单关闭将中止。

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
,您将阻止表单关闭。

但是,内联显示验证错误会是更好的设计/用户体验(通过以某种方式突出显示有问题的字段,显示工具提示等)并阻止用户首先选择“确定”按钮.


17
投票

不要为此使用 FormClosing 事件,您将希望允许用户通过“取消”或单击 X 来关闭对话框。只需实现“确定”按钮的 Click 事件处理程序,并且在您满意之前不要关闭:

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

其中“ValidateControls”是您的验证逻辑。 如果有问题则返回 false。


3
投票

您可以捕获 FormClosing 并强制表单保持打开状态。 为此,请使用事件参数对象的 Cancel 属性。

e.Cancel = true;

它应该会阻止你的表单关闭。


3
投票

这并不能直接回答您的问题(其他问题已经有),但从可用性的角度来看,我希望在输入无效时禁用有问题的按钮。


3
投票

使用此代码:

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

它的问题是用户必须单击两次按钮才能关闭表单;


1
投票

只需在事件函数中添加一行

private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
             {
                this->DialogResult = System::Windows::Forms::DialogResult::None;
             }

0
投票

我希望我有时间找到一个更好的例子,但是使用现有的 Windows 窗体验证技术来做到这一点会更好。

http://msdn.microsoft.com/en-us/library/ms229603.aspx


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;
}

0
投票

我的答案是将默认的确定按钮DialogResult设置为none。

然后,在确定按钮代码的末尾,验证成功后:

this.ButtonOK.DialogResult = DialogResult.OK;
this.Close();

简单,适合我!


-1
投票

您可以在用户点击“确定”按钮之前检查表单。 如果这不是一个选项,请打开一个消息框,指出出现问题,然后以之前的状态重新打开表单。

© www.soinside.com 2019 - 2024. All rights reserved.