If I call Close() in my WinForm, it seems that even though DialogResult is None at the time, right after I call Close() I see that it is set to Cancel.
Does this sound normal?
Or even easier, you can set DialogResult just after Close. For example, assuming ValidateSettings will show the user any problems with the form or return true otherwise:
private void btnOK_Click(object sender, EventArgs e)
{
if (ValidateSettings())
{
SaveSettings();
Close();
DialogResult = DialogResult.OK;
}
}
That is completely normal, as it is the intended behavior. However, it is not equivalent to clicking the red "X" in the top right corner of the Form if you are using an MDI or ShowDialog().
When a form is displayed as a modal dialog box, clicking the Close
button (the button with an X in the top-right corner of the form)
causes the form to be hidden and the DialogResult property to be set
to DialogResult.Cancel. The Close method is not automatically called
when the user clicks the Close button of a dialog box or sets the
value of the DialogResult property. Instead, the form is hidden and
can be shown again without creating a new instance of the dialog box.
Because of this behavior, you must call the Dispose method of the form
when the form is no longer needed by your application.
The DialogResult value can be overridden though:
You can override the value assigned to the DialogResult property when
the user clicks the Close button by setting the DialogResult property
in an event handler for the Closing event of the form.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.dialogresult(v=VS.100).aspx
Related
As the title says, I have a WinForms window that is sometimes setting its DialogResult property to Cancel immediately after ShowDialog is called.
The window is displayed like this:
bool isSuccess = (ShowDialog() == System.Windows.Forms.DialogResult.OK);
Now most of the time, the DialogResult is set to None when the window is first instantiated, as it should be. In these cases, the window will remain open/active until the DialogResult is set to something other than None.
I have even changed this function to look like:
this.DialogResult = System.Windows.Forms.DialogResult.None;
bool isSuccess = (ShowDialog() == System.Windows.Forms.DialogResult.OK);
And still, sometimes, the DialogResult will immediately be Cancel.
There is no where in my code being hit that sets or interacts with the DialogResult property, anywhere, at any time, when it is automaticall set to Cancel.
Also if I break on the line immediately after ShowDialog is called, the entire stack trace leading up to the ShowDialog call is identical - line for line.
Given that nothing is actually interacting with the DialogResult property, I have absolutely no idea how to stop this.
How are you closing the window? If you close it using the X, the result is automatically set to DialogResult.Cancel (see here)
When a form is displayed as a modal dialog box, clicking the Close button (the button with an X in the top-right corner of the form) causes the form to be hidden and the DialogResult property to be set to DialogResult.Cancel. The Close method is not automatically called when the user clicks the Close button of a dialog box or sets the value of the DialogResult property. Instead, the form is hidden and can be shown again without creating a new instance of the dialog box. Because of this behavior, you must call the Dispose method of the form when the form is no longer needed by your application.
EDIT:
If I'm understanding correctly, you also mention that it works correctly "when it's first instantiated". Does that mean you're re-using the same form after closing it? If so, this isn't supported. Once it is closed, you have to create a new instance of the form to show it again.
I have a modal form (login) which I want that on closing it using "X" button, force application to exit.
I tried this:
private void Login_Deactivate(object sender, EventArgs e)
{
Application.Exit();
}
this cause my application to exit on pressing login button (closing). but I want exiting only on "X" button of window.
How can I do it?
Get rid of the Deactivate event, you don't need it.
The issue here is that you cannot tell that just the "X" button was pressed. What you really do is track all the other conditions that cause form close, and react when it's not one of those.
You should leverage the DialogResult enum, and allow the calling application to react, instead of trying to do it all in the Login form.
In your Login form constructor, set the property to None:
public Login()
{
DialogResult = DialogResult.None;
}
Then, in your button handler for "OK", set the property: DialogResult = DialogResult.OK.
If you have a specific Cancel event, you can set DialogResult = DialogResult.Cancel.
Ultimately, you could have a FormClosing event in the Login form, in which you can check this value and react. But more importantly, your calling application can check the result from the login form and react there as well.
I think you should use this.Parent.Application.Exit(), it kills whole application.
Instead of Deactivate event, subscribe to the "FormClosing" event of the "Login" form. Write the same code which you have written.
Keep the Deactivate event only if it is required to close the Application when you click outside login form.
I have a form "Main" and in Main I am creating another form which I use .ShowDialog() to display it. I do this because I don't want the rest of the code to in Main to execute until after the new form is completed. I am allowing a user to minimize the new form to system tray.
The problem: When the form gets minimized it is returning DialogResult.Cancel to the Main form that called it, causing the next line to run early.
Code to create form from Main form:
for(int i = 0; i < lvAll.SelectedItems.Count; i++)
{
this.Hide();
this.run = new RunProfile(this.profiles[lvAll.SelectedItems[i].Text]);
DialogResult result = run.ShowDialog();
MessageBox.Show(result.ToString());
}
In the new form a user will get a list of files that copy... now the user can continue and copy those files and I would expect to return a result of OK and if not I assume they are going to cancel and return Cancel...
Is my only recourse to return Abort from the new form if a user specifies a cancel and assume that a cancel is someone trying to minimize? This just seems odd
You could handle this in a number of ways, one way is like what follows:
MainTestForm mainTestForm = new MainTestForm();
if (mainTestForm.ShowDialog() != System.Windows.Forms.DialogResult.OK)
{
return;
}
You must set the DialogResult state when you close the form like
this.DialogResult = System.Windows.Forms.DialogResult.OK;
I hope this helps.
This is entirely by design. When you hide a modal dialog, the user doesn't have any way to get back to the program. Dialogs don't have a taskbar button and the rest of the windows in the app are disabled so cannot be activated. The only recourse the user would have is to kill your program with Task Manager.
So Winforms does the logical thing, it automatically closes the dialog to avoid this UI trap. And of course you'll get DialogResult.Cancel.
Use proper UI design, a dialog should always have its MinimizeBox property set to False.
I'm not sure what you are trying to achieve with that. However, to get the Dialog to return anything else, you have to set it in the form's (Dialog's) DialogResult property before the form is closed.
You may also use the Form_Closing event of the dialog to set the DialogResult property to what you want. This is done before the form closes.
Here is a quote from MSDN regarding ShowDialog:
When this method is called, the code following it is not executed
until after the dialog box is closed.
After further reading it does state the X does not close the form but hides it and so you must dispose of it:
When a form is displayed as a modal dialog box, clicking the Close
button (the button with an X in the top-right corner of the form)
causes the form to be hidden and the DialogResult property to be set
to DialogResult.Cancel. The Close method is not automatically called
when the user clicks the Close button of a dialog box or sets the
value of the DialogResult property. Instead, the form is hidden and
can be shown again without creating a new instance of the dialog box.
Because of this behavior, you must call the Dispose method of the form
when the form is no longer needed by your application.
It seems this same issues applies to minimizing a userform as well.
I have a windows form with multiple controls and OK and Cancel buttons. In the Click event handler of OK button, it checks to see if there are errors on the form. I need the form to stay open if there are errors. But the code below is not working. If there are errors, it is closing the form and returning to the caller. And I have the below two lines to invoke and show the form.
PtForm paymentForm = new PtForm();
ptForm.ShowDialog();
private void btnOk_Click(object sender, EventArgs e)
{
this.ValidateChildren(ValidationConstraints.Visible);
string ErrorString = GetValidationErrors();
MessageBox.Show(ErrorString, "Errors");
if (!string.IsNullOrEmpty(ErrorString))
{
return;
}
//Processing
}
Thanks for any help.
There's nothing in this code that will close the form. Therefore, the culprit must be outside this code.
Did you set your OK button's DialogResult property to DialogResult.OK? That would explain why the form is closing. AFAIK, if you set DialogResult on the button, that's what happens -- there's no way to veto it in code.
So in that case, you would need to go back to the designer and set the button's DialogResult back to None. Then at the end of your btnOk_Click method, once you've validated all the input and decided that it's safe to close the dialog, add a line that sets your Form's DialogResult property to OK.
Remove DialogResult property of a button-i.e. set it to None.
I have been dealing with strange problem. I am using KryptonForm in a project. I have a form (say form1) and I need to open another form on a button click from this form. Here is the code:
void btn_click(object sender, EventArgs e)
{
Visible = false;
ShowInTaskbar = false;
var f = new Form2();
f.ShowDialog();
Visible = true;
ShowInTaskbar = true;
}
The problem is that when the Form2 closes it closes the Form1 also. I have tried setting DialogResult = DialogResult.None from Form2 but of no avail. Please help me.
I am always using this technique and this thing has never happened.
Yes, this code is troublesome. It goes wrong when the user closes the dialog. Windows must then find another window to give the focus to. There isn't any left in your app, your main window is invisible. It then picks a window of another app. Odds are good, for example, that this will be a window inside Visual Studio. A big one. Your main form now disappears behind it.
You need to make sure that your main window is visible again before the dialog closes. You can do so by subscribing to the dialog's FormClosing event handler. For example:
private void button1_Click(object sender, EventArgs e) {
using (var dlg = new Form2()) {
dlg.StartPosition = FormStartPosition.Manual;
dlg.Location = this.Location;
dlg.FormClosing += (s, ea) => this.Show(); // <=== Here
this.Hide();
if (dlg.ShowDialog() == DialogResult.OK) {
// etc...
}
}
}
Bugged me for days!! Found this: https://bytes.com/topic/net/answers/769433-c-showdialog-inside-showdialog-closing-both-return
The result was being passed down and I dont know why. But if after the .ShowDialog() I just put this.DialogResult = DialogResult.None, it will fix it. This shouldnt happen in the first place, but this fixes it, so I am not too bothered.
You can also try changing the dialogResult on the button itself to "None" or deleting the this.Btn1.DialogResult... from the designer which worked for some people.
https://social.msdn.microsoft.com/Forums/vstudio/en-US/543093ad-1860-4428-bae1-b0d4f112e04b/showdialog-closes-parent?forum=csharpgeneral
I know this is an old post, but I ran into this, and in my case the accepted answer (at the time I am writing this) is not helpful at all. The answer by #blind Skwirl led me to the culprit.
After 20 years of .Net programming (since it was introduced), I never noticed that BUTTONS have a "dialogresult" property. I always just set the forms "cancelbutton" and "acceptbutton" properties. What I found in my case was that (because I was doing a lot of copy-pasting of buttons), I had a bunch of buttons (not forms) that themselves had their "dialogresult" property set to "cancel", which meant that I would click a button on a dialog that would open another dialog, the "ok" button on the dialog had its result set to "cancel", and the button on the parent form ALSO had its result set to "cancel", so the dialog would close (with a result of cancel) and then the PARENT form would close with a result of cancel, confusing the heck out of me... so...
Just make sure all of your buttons have their dialogresult property set to NONE (or whatever the actual proper setting is that you want).
Bottom line, if a BUTTON (not the form) has its dialogresult property set to anything other than NONE, the form will close with that result when it is clicked (after any click event code has completed).
I hope that helps someone out there.