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

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

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.

Given that you've specified you want a pop error dialog, one way of doing this is to move your validation into a OnClosing event handler. In this example the form close is a 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.

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.

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.

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.

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;

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

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

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

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.

Related

Check if Form is closing

I have a method that fires on a "Leave" event:
private void cmbBox1_Leave(object sender, EventArgs e)
{
bool error = true;
if (something == true)
{
//do stuff...
error = false;
}
if (error == true)
{
MessageBox.Show("Error!")
}
}
Problem is, that closing the form counts as "leaving focus" from the control, so when I close the form, the message box pops up. Is there a way I can catch the Form closing as an invalid parameter? I.e.
if (error == true && this.FormClosing == false)
{
MessageBox.Show("Error!")
}
Try using the Validating event instead of Leave.
Then in FormClosing, you can set this.AutoValidate = AutoValidate.Disable; and your validation won't be fired any more.
If you close the form via an OK or Cancel button, you may need to set CausesValidation = false on those buttons as well (maybe you want validation on OK, though).

How to set focus to a Control on the Form when cancelling FormClosing event?

I am validating input on textboxes on the FormClosing event of my Form and if the user decides to cancel closing, I set e.Cancel = true so as to stop the FormClosing event. I then try to set focus to the first textbox but this is not working.
private void AddDriver_Window_FormClosing(object sender, FormClosingEventArgs e)
{
if (this._Cancel(sender, e))
{
e.Cancel = true;
this.textboxFirstName.Focus();
}
}
If you are interested in seeing the ._Cancel method I asked an unrelated question earlier.
I tried this one Check this is it work for you..
private void AddDriver_Window_FormClosing(object sender, FormClosingEventArgs e)
{
if( DialogResult.Cancel == MessageBox.Show("Do you want to exit programm","Alert",MessageBoxButtons.OKCancel))
{
e.Cancel = true;
textBox1.Focus();
}
}
this will popup a message box and if click cancel then automatically focus on the textbox1.

Validating user's input before continuing program execution

I have created a program that contains (for now) 2 forms.
In the first form I am asking the user for a file. After the user has selected a file, another form is called followed by closing of the current form.
An if statement indicates if the user has inserted a file when the Open File button is pressed, and if not, the second form will not be loaded.
The problem is that if the user clicks the Close button on the first form (the current one), the form closes and the next one is called.
The options of the next form are based on the user's input in the first form (where the user is asked to select a file), so if the second form is called when the user cancels the first form, it will create problems for methods in the second form.
Any ideas about how to handle the Close Button?
If you want to prevent closing the form you can handle the event
bool cancel = true;
protected override void OnFormClosing(FormClosingEventArgs e)
{
e.Cancel = cancel;
base.OnFormClosing(e);
}
Remember to change cancel to false when it's done to close the form.
There is an event named "FormClosing" on forms.
A quick sample:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Are you sure you want to quit?", MessageBoxButtons.YesNo) == DialogResult.No)
{
e.Cancel = true;
}
}
I am assuming that you have an OpenfileDialog (to allow the user to select a file),and a button probably named Open File to pass the filename to next form.If this is the case,then you can try to to disable the open button if no file has been selected.
Consider the code below as the function where all logic takes place;
private void BrowseFile()
{
//dlgopenfile is the name of Openfiledialog that allows the user to browse for a file.
//string filename is the name of selected file if any.
//Form2 is the next form.
try
{
switch (dlgopenfile.ShowDialog())
{
case DialogResult.OK://If Ok(Yes) button is pressed on Openfiledialog.
filename = dlgopenfile.FileName;
break;
case DialogResult.Cancel://If Cancel button is pressed on Openfiledialog.
filename = "";
break;
}
if (filename.Length >= 1)
{
if (File.Exists(filename) == true)
{
ButtonOpenFile.Enabled = true;
}
else
{
ButtonOpenFile.Enabled = false;
throw new FileNotFoundException("The file you selected does not exist.");
}
}
}
catch (FileNotFoundException ex)
{
MessageBox.Show(ex.Message, "Form1", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
The next function occurs if user tries to close the form in mid session.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
switch (MessageBox.Show("Do you want to exit ?", "Form1", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk))
{
case DialogResult.Yes:
this.Close();
break;
case DialogResult.No:
e.Cancel = true;
break;
}
}
catch (Exception)
{
//Exception handling code goes here.
}
}
Finally the function below calls Form2's constructor with the selected file as argument.
private void ButtonOpenFile_Click(object sender, EventArgs e)
{
//This Button is enabled only if the file has been selected and if its exists.
Form2 form2 = new Form2(filename);//filename is the name of selected file,as decided in function BrowseFile().
this.Close();//Close Form1.
form2.ShowDialog();//Show Form2 as modal dialog.
}
Hope it would help you achieve what you need.Anything more,please let me know.
Proposally you start you form with form.ShowDialog(), which returns DialogResult. You should check whether it is DialogResult.Ok or whether form.DialogResult != DialogResult.None. In the form, if the user inserts the file you can set the form.DialogResult explicitely to DialogResult.Ok
Just you can handle the close event with your own logic
private void Form1_FormClosing_1(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show(text:"Are you sure you want to quit?",caption:string.Empty,buttons: MessageBoxButtons.YesNo) == DialogResult.No)
{
e.Cancel = true;
}
}

Retain the dialog to be open after ShowDialog result

I'm opening a modal dialog asking the user to fill certain fields.
if(dlgUserDetail.ShowDialog() == DialogResult.OK)
{
}
On click of OK, the control comes to the parent form where I'm validating the user input.
If the validation fails, I wanted to keep the dialog to be open with the old values. Since it is modal dialog, the form gets closed.
It seems to be a common problem as I see many discussion on net, but nowhere I was able to find a solution.
Please let me know how to solve this problem. Thanks.
Regards
ArunDhaJ
If it is your dialog you could add a CancelEventArgs event called Validate or InputOk (similar to FileOk in OpenFileDialog) and have your main form check the input in a method. Before calling DialogResult = DialogResult.OK in your dialog, you add a ´onValidate` call to check if the input is valid.
{
// dialog
{
if (onValidate()) {
DialogResult = DialogResult.OK;
}
}
private bool onValidate() {
CancelEventHandler handler = Validate;
if (handler == null) {
return true;
}
CancelEventArgs args = new CancelEventArgs();
handler(this, args);
return args.Cancel;
}
}
{
// form
{
dlgUserDetail.Validate += valid;
if(dlgUserDetail.ShowDialog() == DialogResult.OK) { }
}
private void valid(object sender, CancelEventArgs e) {
// check input and set
e.Cancel = true;
// if not valid
}
}
One solution is to put validate logic into dlgUserDetail form and invoke it on OnClosing event. If the validation failed then prevent the form from closing.

C# Validate before leaving accept_button event

Excuse me if this is a silly question but i'm a beginer here.
I have a simply custom dialog with two buttons: Accept and Cancel. The Accept button is the acceptButton of the form.
I want to do some validations on the Accept_Click event and decide if i can close the dialog or not, but everytime it leaves this method, the dialog automatically closes itself and returns Ok.
What can I do to stop the dialog from closing itself? or i have to do things in some other way?
thanks
I would have a form level variable (call it _vetoClosing) In the accept button's Click event, I would run validation and set the variable based on that:
private void acceptButton_Click(object sender, EventArgs e)
{
// Am I valid
_vetoClosing = !isValid();
}
Then in the FormClosing event, I would cancel close if _vetoClosing is true
private void Form_FormClosing(object sender, FormClosingEventArgs e)
{
// Am I allowed to close
if (_vetoClosing)
{
_vetoClosing = false;
e.Cancel = true;
}
}
Turning Accept button off is suboptimal because you loose the Enter to Press functionality.
A cleaner solution would be to set DialogResult to None:
private void acceptButton_Click(object sender, EventArgs e)
{
if (!isValid()) {
this.DialogResult = System.Windows.Forms.DialogResult.None;
}
}
I would validate as the controls change, and only enable the Accept button if the whole form is valid.
This would allow you to keep your button as the default button (AcceptButton), but prevent this from occurring.
Is the AcceptButton or CancelButton on the form set to that button? If so, try unsetting it and manually setting DialogResult in your handler when you want to close the dialog.

Categories

Resources