qster
qster

Reputation: 1149

Preventing a dialog from closing in the button's click event handler

I have a dialog that I show with <class>.ShowDialog(). It has an OK button and a Cancel button; the OK button also has an event handler.

I want to do some input validation in the event handler and, if it fails, notify the user with a message box and prevent the dialog from closing. I don't know how to do the last part (preventing the close).

Upvotes: 73

Views: 96067

Answers (11)

trevor
trevor

Reputation: 267

My answer is to set the default ok button DialogResult to none.

then, at the end of the ok button code, after validation has succeeded:

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

simple and works for me!

Upvotes: 0

ChrisF
ChrisF

Reputation: 137108

Given that you've specified you want a pop error dialog, one way of doing this is to move your validation into a Form.OnFormClosing event handler. In this example the form close is aborted if the user answers yes to the question in the dialog.

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

By setting e.Cancel = true you will prevent the form from closing.

However, it would be a better design/user experience to display the validation errors inline (via highlighting the offending fields in some way, displaying tooltips, etc.) and prevent the user from selecting the OK button in the first place.

Upvotes: 56

Ata Hoseini
Ata Hoseini

Reputation: 137

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

Upvotes: 0

Croko
Croko

Reputation: 97

Just add one line in the event function

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

Upvotes: 1

Arjan
Arjan

Reputation: 2010

You can cancel closing by setting the Form's DialogResult to DialogResult.None.

An example where button1 is the AcceptButton:

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

When the user clicks button1 and the validate method returns false, the form will not be closed.

Upvotes: 163

cigos emmanuel
cigos emmanuel

Reputation: 31

Use this code:

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

The problem of it is that the user has to clic two times the buttons for closing the forms;

Upvotes: 3

Hans Passant
Hans Passant

Reputation: 941218

Don't use the FormClosing event for this, you'll want to allow the user to dismiss the dialog with either Cancel or clicking the X. Simply implement the OK button's Click event handler and don't close until you are happy:

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

Where "ValidateControls" is your validation logic. Return false if there's something wrong.

Upvotes: 17

Mesh
Mesh

Reputation: 6422

I wish I had time to find a better example, but you would be much better off using the existing windows forms validation techniques to do this.

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

Upvotes: 0

Benjol
Benjol

Reputation: 66531

This doesn't directly answer your question (other already have), but from a usability point of view, I would prefer the offending button be disabled while the input is not valid.

Upvotes: 3

Adrian F&#226;ciu
Adrian F&#226;ciu

Reputation: 12552

You can catch FormClosing an there force the form to remain opened. use the Cancel property of the event argument object for that.

e.Cancel = true;

and it should stop your form from closing.

Upvotes: 3

Icono123
Icono123

Reputation: 3950

You can probably check the form before the users hits the OK button. If that's not an option, then open a message box saying something is wrong and re-open the form with the previous state.

Upvotes: -1

Related Questions