I have this sample code to show an alert MessageBox,
if (cmprLanguage != 0 || cmprmaxCase != 0 )
{
DialogResult result = MessageBox.Show("Alert message", "Alert", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
if (result == DialogResult.OK)
{
loginscreen obj = new loginscreen();
this.Close();
obj.Show();
}
else
{
settings obj = settings(); //this re-load this form i need to show this form without reload
obj.show();
}
}
else
{
loginscreen obj = new loginscreen();
this.Close();
obj.Show();
}
If user clicks cancel button I need to close the MessageBox,if they click ok I need to perform the process given inside OK block. Now what happen is if I click Cancel button the application redirect to home screen.
Update:
I had written a closed event for close icon in form screen.Previously when i click close icon it directly takes me to login screen because login screen is behind this form screen.Some times user may enter data and without save if he hit close icon i have raise a messagebox to alert the user.But now if i click cancel it again takes me to login screen and if i click ok it perform the task inside the condition.If i click Cancel i need to show the current screen with the action performed(without reload of page)
Is it possible to do this?
Your code is already working as expected. But for clearance you could put the result of the MessageBox.Show() in a variable instead. This makes it easier to maintain and process in further code. Like this:
DialogResult result = MessageBox.Show("Settings not saved", "Alert", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
And then handle it in code:
if(result == DialogResult.OK)
{
//Show new data
}
else if (result == DialogResult.Cancel)
{
//Show current data
}
Update:
Your code is not correct they way you've provided it to us: you cannote have two else statements after eachother.
Why don't you just leave the else part away. Only perform an action when the user clicks OK. When the user clicks OK, that means he'll leave the current form without saving the pending changes. When he chooses Cancel, it means that he wants to stay wherever he is at that moment:
DialogResult result = MessageBox.Show("Settings not saved", "Alert", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
if (result == DialogResult.OK)
{
//User leaves without saving pending changes
loginscreen ob = new loginscreen();
this.Close();
ob.Show();
}
//No else: just stay wherever you are.
DialogResult result = MessageBox.Show("Settings not saved", "Alert", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
if (result == DialogResult.OK)
{
loginscreen ob = new loginscreen();
this.Close();
ob.Show();
}
In my opinion this actually satisfies your needs. It is your original code, let me explain.
The MessageBox gets shown and asks the user if he/she wants to Cancel or agrees (OK) with the data being dropped because the form gets closed. Then, as your code was already designed, it creates a new loginscreen and allows the user to do other stuff.
This actually appears to be all you need. You want the user to stay on the current form is the Cancel-button is clicked, which is exactly what happens if you only use this particular piece of code. No else is needed because nothing else needs to happen.
If you do want other code to be executed in the else-statement, you could think about creating a new form and placing OK and Cancel buttons on that yourself (create your own "custom MessageBox"). This will allow you some more options if really needed. But looking at what you are trying to achieve, you are good with the current set up of only an if and no else-statements.
Related
I am unable to determine why the following code fails to save changes to database during FormClosing event:
private void frmClient_FormClosing(object sender, FormClosingEventArgs e)
{
if (bAreChanges)
{
DialogResult dialogResult = MessageBox.Show("Do you wish to save the changes to the database?",
"Confirmation", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
if (dialogResult == DialogResult.Yes)
{
using (var context = new SomeEntities()) {
var value = "abc";
context.sometable.Add(new sometable() {somefield = value} );
context.SaveChanges();
//the same exact code works when executed from a simple button click that is placed on this form.
}
this.Validate(); // even added this line as suggested in another Stackoverflow question
}
else if (dialogResult == DialogResult.No)
{
}
else
{
e.Cancel = true;
}
}
}
Perhaps some part of SaveChanges() is asynchronous and therefore the Form disposes before the database operation is executed?
Edit: This is a child form, not the main form - the application keeps running after this form is closed. If this is somehow relevant.
Putting this.Validate() before the database operations made it work. I would, however, like to know why is that relevant in this case.
i am pretty newbie for coding. Here is i am having a problem:
private void pano_FormClosing(object sender, FormClosingEventArgs e)
{
DialogResult dialog = MessageBox.Show("Uygulamadan çıkış yapmak istediğinizden emin misiniz?", "Çıkış", MessageBoxButtons.YesNo);
if (dialog == DialogResult.Yes)
{
Application.Exit();
}
else if (dialog == DialogResult.No)
{
e.Cancel = true;
}
My purpose with this code block to ask user "are sure to quit" but unfortunetly when i close the application, i got notification window for 3 times? Is there any idea why thats happening or any solution?
Thanks a lot.
Nuri.
Firstly, as Steve pointed out, remove the 'Yes' part - if not explicitly canceled, the event will close that form as a result of clicking.
Now, for the problem of yours. Seems like your alert is called twice. I was able to solve that easily by making a static bool close_alert_shown, and when the first alert is shown, set it to true so that the next alert won't pop up.
Final code looks like that:
if (close_alert_shown) return;
close_alert_shown = true;
DialogResult dialog = MessageBox.Show("Uygulamadan çıkış yapmak istediğinizden emin misiniz?", "Çıkış", MessageBoxButtons.YesNo);
if (dialog == DialogResult.No)
{
e.Cancel = true;
close_alert_shown = false;
}
And on the top of the form (before the public Form1() contructor line):
static bool close_alert_shown = false;
What i suspect is when application is exiting, it is again calling form closing since we have subscribed for that event. I assume, simple fix would be unsubscribe from the event before calling exit.
this.FormClosing-=Form1_FormClosing;
Application.Exit();
I have a windows forms method that gets called:
// fire up the form
ViewportRenumberingForm form = new ViewportRenumberingForm(pickedRef, doc);
form.ShowDialog();
Then inside of that form I have a routine that gets run:
private void btnOK_Click(object sender, EventArgs e)
{
renumberViewports();
}
now if during execution of renumberViewports() it encounters a certain condition I am asking it to initiate a sub form to get user input on how to proceed:
if (openAdditionalForm)
{
ViewportRenumberingForm2 subForm = new ViewportRenumberingForm2();
var result = subForm.ShowDialog();
if (result == DialogResult.OK)
{
// get all values preserved after close
bool selected = subForm.ReturnSelected;
bool unselected = subForm.ReturnUnselected;
if (selected)
{
//do something
}
if (unselected)
{
//do something
}
}
else if (result == DialogResult.Cancel)
{
this.Show();
}
}
Now, the question is: When user hits Cancel I want to return to my main form and basically start over. That means that user can re-enter any information and hit that btnOK_Click() and renumberViewports() will get executed again. It's basically that I want ability for user to just acknowledge that their current input will cause an error, show them that in a sub form, allow them to cancel to re-enter inputs.
Then i want to re-execute it and close the form if there are no errors.
Right now, i got everything up to the Cancel input working. When user hits Cancel I return to my main form, but hitting OK on it, doesnt re-execute the renumberViewports() command.
Any help will be appreciated.
If I understand what you are trying to do, in your renumberViewports() method, change your DialogResult.Cancel conditional block to this:
else if (result == DialogResult.Cancel)
{
// this will close this form and set the result to 'Cancel'
this.DialogResult = DialogResult.Cancel;
}
Then, in you main form, instead of simply:
ViewportRenumberingForm form = new ViewportRenumberingForm(pickedRef, doc);
form.ShowDialog();
... I would change that to a loop that keeps reopening the ViewportRenumberingForm form until the result is not Cancel:
DialogResult result = DialogResult.Cancel;
while (result == DialogResult.Cancel)
{
ViewportRenumberingForm form = new ViewportRenumberingForm(pickedRef, doc);
result = form.ShowDialog();
}
I have a WinForms application that checks for pending changes whenever the user hits the cancel button. If there are pending changes, I prompt the user to see if they are sure they wish to cancel. If they do, I close the form. If not, I just return. However, the form is closing anyways. After some debugging, I realized it was because this particular button is set to the form's CancelButton, so clicking it caused the form to close. To verify, I removed the CancelButton property, but the behavior persisted.
How can I prevent this automatic closing? Here is my event handler code:
private void closeButton_Click(object sender, EventArgs e)
{
DialogResult dr = DialogResult.Yes;
if (changesMade)
{
dr = MessageBoxEx.Show(this, "Are you sure you wish to disregard the changes made?", "Changes Made", MessageBoxButtons.YesNo);
}
if (dr == DialogResult.Yes)
{
Close();
}
else
{
//TODO:
}
}
In the above code, the form should only close if there are no changes made, or if the user chose to disregard them. I made changes, and clicked 'No' to the DialogBox, but the form still closed. With and without the button set as the form's CancelButton.
Just set the property DialogResult of the form to the enum DialogResult.None
....
if (dr == DialogResult.Yes)
{
Close();
}
else
{
this.DialogResult = DialogResult.None;
}
or simply:
if (dr != DialogResult.Yes)
this.DialogResult = DialogResult.None;
The form closes automatically because the property DialogResult of the button is not set to DialogResult.None in the Forms Designer. In this scenario, the WinForms engine takes that value and assign it to the DialogResult property of the whole form causing it to automatically close. This is usually used in the calling code of the form to distinguish between a Confirm and a Cancel button
In the example below suppose that on the frmCustomers there are two buttons, one with the DialogResult property set to DialogResult.OK and another set to DialogResult.Cancel. Now if the user hits the OK button you know, in the calling code what to do with the inputs for your new customer
using(frmCustomers f = new frmCustomers())
{
if(f.ShowDialog() == DialogResult.OK)
{
// Execute code to save a customer
}
}
Following up on my comment, this is what I do for an internal tool I wrote recently:
private void Form_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = !PromptUnsavedChanges();
}
private bool PromptUnsavedChanges()
{
if (HasFormChanged()) //checks if form is different from the DB
{
DialogResult dr = MessageBox.Show("You have unsaved changes. Would you like to save them?", "Unsaved Changes", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
if (dr == System.Windows.Forms.DialogResult.Yes)
tsmiSave_Click(null, null); // Saves the data
else if (dr == System.Windows.Forms.DialogResult.Cancel)
return false; // Cancel the closure of the form, but don't save either
}
return true; // Close the form
}
The logic could probably cleaned up from a readability point of view, now that I'm looking at it months later. But it certainly works.
With this you simply just call this.Close(); in your button click event. Then that event is what handles the prompting and decides if it should actually close or not.
As I said in the title I am creating a program. However, I am facing the problem of the FormClosing event executing twice. The message box appears and the buttons perform their purpose well, but when I click "Yes" or "No", it repeats itself. Thankfully the "Cancel" button doesn't have this problem.
private void Form1_FormClosing (object sender, FormClosingEventArgs e)
{
DialogResult dialog = MessageBox.Show("Do you want to save your progress?", "Media Cataloguer", MessageBoxButtons.YesNoCancel);
if (dialog == DialogResult.Yes)
{
SaveFileDialog savefile = new SaveFileDialog();
savefile.Filter = "Text files|*.txt";
savefile.Title = "Save As";
savefile.ShowDialog();
System.IO.FileStream fs = (System.IO.FileStream)savefile.OpenFile();
Application.Exit();
}
else if (dialog == DialogResult.No)
{
MessageBox.Show("Are you sure?", "Media Cataloguer", MessageBoxButtons.YesNo);
Application.Exit();
}
else if (dialog == DialogResult.Cancel)
{
e.Cancel = true;
}
}
Nothing else I have found had helped me very much. Like I said earlier, the message box appears twice. That is my only problem. Everything else for this void works fine.
Your problem is that you are calling Application.Exit(). As MSDN says,
The Exit method stops all running message loops on all threads and
closes all windows of the application
In other words, it will fire the form closing event again.
To get around this, use Environment.Exit(0) instead.
Your second MessageBox does not make sense and you do not have to exit the application.
The window should close if you do not set e.Cancel to true:
https://msdn.microsoft.com/en-us/library/system.windows.window.closing%28v=vs.110%29.aspx
private void Form1_FormClosing (object sender, FormClosingEventArgs e) {
DialogResult dialog = MessageBox.Show("Do you want to save your progress?", "Media Cataloguer", MessageBoxButtons.YesNoCancel);
if (dialog == DialogResult.Yes) {
SaveFileDialog savefile = new SaveFileDialog();
savefile.Filter = "Text files|*.txt";
savefile.Title = "Save As";
savefile.ShowDialog();
System.IO.FileStream fs = (System.IO.FileStream)savefile.OpenFile();
} else if (dialog == DialogResult.No) {
if(MessageBox.Show("Are you sure?", "Media Cataloguer", MessageBoxButtons.YesNo) == DialogResult.No){
e.Cancel = true;
}
} else if (dialog == DialogResult.Cancel) {
e.Cancel = true;
}
}
I would not quit the app in a window closing event.
It is not designed to perform that task.
You could use the project settings to define when the application quits.
Or if you need more control than that, you may want to handle it in the App.cs.
But I wouldn't do it in here.
You really shouldn't be throwing more than a single messagebox at the user... you might want to read this, this, and this. That said, I consider exiting with a prompt to save as one of the good spots for one, but not two.
You've already got the correct mechanism in place (they can answer Yes, No, or Cancel). Revise your question to be more clear to the user: "Would you like to save your work before exiting?" If they cancel, then cancel like you are using e.Cancel. Otherwise, just let the form close on it's own.
If they answer no, don't ask again. I can hear them now...
"I already told you, just EXIT!!!"