I have a simple modal form in which I have to check user entered data. But after validation the form gets closed. It behaves like this because of not empty DialogResult property but I need this value for other purposes (in a parent form)
Any ideas?
A little code to clear things up
//This method creates and calls a modal form.
public static Definition edit(Definition w)
{
EditForm ed = new EditForm();
DialogResult dr = ed.ShowDialog();
if (dr == DialogResult.OK)
{
//update some fields of passed object
}
//other code
}
private void btnSave_Click(object sender, EventArgs e)
{
if (validateForm())
{
DialogResult = DialogResult.Yes;
Close();
}
}
I would do it this way:
private void btnSave_Click(object sender, EventArgs e)
{
if (validateForm())
{
DialogResult = DialogResult.Yes;
Close();
}
else
{
DialogResult = DialogResult.None;
}
}
I.e. as you said, clear the DialogResult.
Add a FormClosing event handler and then if the validation fails set e.Cancel = true:
private void EditForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.DialogResult == DialogResult.OK)
{
e.Cancel = !ValidateInput();
}
}
This will leave you sub form open and let the user correct the mistakes. You can check whether the "OK" or "Cancel"/Window Close button has been clicked by checking the DialogResult and only performing the validation if it's OK.
Related
My form contains a button named as close. I just put the below code in the close button click... Then the 2nd code set is for the form closing. But if I execute this when I click the close button a MessageBox will appear. When I click the "Yes" button, the form is not closing but if I click the "Yes" button second time the form will be closed. What is the reason? Can you, please, help me?
private void btnClose_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Are You Sure You Want To Close This Form?",
"Close Application",
MessageBoxButtons.YesNo) == DialogResult.Yes)
{
// MessageBox.Show("The application has been closed successfully.",
// "Application Closed!",
// MessageBoxButtons.OK);
System.Windows.Forms.Application.Exit();
}
else
{
this.Activate();
}
}
-------------------------------------
private void frminventory_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Are You Sure You Want To Close This Form?",
"Close Application",
MessageBoxButtons.YesNo) == DialogResult.Yes)
{
System.Windows.Forms.Application.Exit();
}
else
{
this.Activate();
}
}
Do not close/exit Application, but Form:
private void btnClose_Click(object sender, EventArgs e) {
// On btnClose button click all we should do is to Close the form
Close();
}
private void frminventory_FormClosing(object sender, FormClosingEventArgs e) {
// If it's a user who is closing the form...
if (e.CloseReason == CloseReason.UserClosing) {
// ...warn him/her and cancel form closing if necessary
e.Cancel = MessageBox.Show("Are You Sure You Want To Close This Form?",
"Close Application",
MessageBoxButtons.YesNo) != DialogResult.Yes;
}
}
Edit: Usually we ask direct questions to user (it's unclear what wrong things can arise if I just "Close This Form"), e.g.
private void frminventory_FormClosing(object sender, FormClosingEventArgs e) {
// Data has not been changed, just close without pesky questions
if (!isEdited)
return;
// If it's a user who is closing the form...
if (e.CloseReason == CloseReason.UserClosing) {
var action = MessageBox.Show(
"You've edited the data, do you want to save it?"
Text, // Let user know which form asks her/him
MessageBoxButtons.YesNoCancel);
if (DialogResult.Yes == action)
Save(); // "Yes" - save the data edited and close the form
else if (DialogResult.No == action)
; // "No" - discard the edit and close the form
else
e.Cancel = true; // "Cancel" - do not close the form (keep on editing)
}
}
So, because i can't comment, i would do something like this.
//Create this variable
private bool _saved = true;
public Form1()
{
InitializeComponent();
}
private void btnSave_Click(object sender, EventArgs e)
{
DoSomething();
_saved = true;
}
//Raised when the text is changed. I just put this for demonstration purpose.
private void textBox1_TextChanged(object sender, EventArgs e)
{
_saved = false;
}
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (_saved == false)
{
var result = MessageBox.Show("Are you sure you want to close?\nYou may have unsaved information", "Information", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information);
if (result == DialogResult.Yes)
{
_saved = true;
Application.Exit();
}
else
e.Cancel = true;
}
}
Hope this can solve yor problem
I have a Save button on my WinForm which saves the form information and then closes the form using the this.Close() statement.
There is however another way of closing the form and that is the X button.
I am using the FormClosing event to ask a question before the form is closed.
private void EmailNewsletter_FormClosing(object sender, FormClosingEventArgs e)
{
DialogResult dr = MsgBox.Show("Are you sure you want to dimiss this newsletter?", "Dismiss Newsletter", MsgBox.Buttons.YesNo, MsgBox.Icon.Question);
if (dr == System.Windows.Forms.DialogResult.Yes)
{
this.Newsletter = null;
}
else
{
e.Cancel = true;
}
}
But the way of handling the close form depends on how the form is closed. If the user clicks on the Save button, the form should be closed without a question. It is only when user clicks on the X button that the question should be asked.
How can I let my form know what the Close command comes from?
A simple boolean flag should do the trick:
private bool saveClicked = false;
private void btnSave_click(object sender, EventArgs e)
{
saveClicked = true;
}
private void EmailNewsletter_FormClosing(object sender, FormClosingEventArgs e)
{
if(saveClicked)
return;
DialogResult dr = MsgBox.Show("Are you sure you want to dimiss this newsletter?", "Dismiss Newsletter", MsgBox.Buttons.YesNo, MsgBox.Icon.Question);
if (dr == System.Windows.Forms.DialogResult.Yes)
{
this.Newsletter = null;
}
else
{
e.Cancel = true;
}
}
I made a custom dialog box in WPF. I want , when the user clicks X the dialogBox will be opened, if he wants to exit he should click "yes", if not he should click "no".
static public bool? close;
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
this.Hide();
WindowClose windowClose = new WindowClose();
windowClose.ShowDialog();
close = windowClose.DialogResult;
if (close == true)
{
Application.Current.Shutdown();
}
else
{
//DONT CLOSE THE APPLICATION AND SHOW THE CURRENT WINDOW
}
}
the code of the dialog box:
private void button1_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
this.Close();
}
private void button2_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
this.Close();
}
Not sure if it works differently in WPF, but in standard winforms in the code for the dialog box you'd set (for example) the DialogResult to DialogResult.OK (yes) and DialogResult.Cancel (no). You wouldn't need to close the form as this is done automatically when you set the DialogResult
Then in the main form you'd have
If (windowClose.ShowDialog() == DialogResult.OK
{
Application.Current.Shutdown();
}
else
{
//DONT CLOSE THE APPLICATION AND SHOW THE CURRENT WINDOW
}
I have simple Form1 with datagridview and I've enabled editing and adding.
Now, when I click on closing form button, and if some of existing cell values are changed or new row has been added I want dialogue box to open (for example, asking me if I want to save changes or don't), and if there is no changes , just to perform simple form closing.
How can I accomplish this ?
Ok, here is what I've got so far.
I'm trying to this one using CSLA framework, I've created root editable collection public class PDVCollection : BusinessBindingListBase<PDVCollection, PDV> and editable child public class PDV : BusinessBase<PDV>
On Form1 I've got this code
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public PDVCollection s;
private void Form1_Load(object sender, EventArgs e)
{
bindingSource1.DataSource = PDVCollection.GetAll();
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
s = (PDVCollection)bindingSource1.DataSource;
s = s.Save();
bindingSource1.DataSource = s;
}
private void toolStripButton3_Click(object sender, EventArgs e)
{
if (dataGridView1.CurrentCell.RowIndex > -1)
{
PDV sel = (PDV)dataGridView1.CurrentRow.DataBoundItem;
s = (PDVCollection)bindingSource1.DataSource;
s.Remove(sel);
s = s.Save();
}
}
i want to cut s = s.Save(); from both toolStripButton1_Click and toolStripButton3_Click and If something is changed/added/deleted and I perform closing event
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (//some code to implement)
{
DialogResult dialogResult = MessageBox.Show("Do you want to save changes", "Message", MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.Yes)
{
s = (PDVCollection)bindingSource1.DataSource;
s = s.Save();
}
else if (dialogResult == DialogResult.No)
{
this.DialogResult = DialogResult.OK;
}
}
}
If you're doing databinding to a DataSource, then you can use the datasource to determine whether it has been changed in the FormClosing or FormClosed event. The actual implementation would be up to the type of datasource you are using.
If you're not specifying a datasource, then the data by default can be accessed in the Rows collection of the DataGrid. That collection class doesn't have a "changed" flag by default, but it DOES have a CollectionChanged event that you could hook up.
So, in your form's construtor, you could do a
DataGrid1.CollectionChanged += Rows_CollectionChanged;
And then in your Rows_CollectionChanged you could set a flag that data has changed and needs to be saved. Obviously giving much more detail would require knowing more about the details of your datagrid and datasource.
Per the comments below, you may want more than a flag depending on how you define "changed". If you need to know that a field was changed, then changed back to the original value then as a commenter below says a simple flag wouldn't do it, and you might need to store a shadow copy of the original data.
That said, if you need to handle really complicated undo scenarios you're going to want datasource designed for that, which is a whole different topic.
EDIT: If you're using CSLA objects as your data source, then there should be an IsDirty flag on the objects. So just iterate over the items in the datasource on the FormClosed event and check the IsDirty flag for each object.
You need to create flag variable and initially set it to false
bool isAnythingChange = false;
And make this variable to true on new row add, or value change event. For sample I have shown below
void txt_Change(object sender, EventArgs e)
{
isAnythingChange = true;
}
And while you are handling form closing event make point to check isAnythingChange. If it's value is true then ask for confirmation or else close form without confirmation.
EDIT:
As you maintain in your question, updated code may be like this.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (isAnythingChange)
{
DialogResult dialogResult = MessageBox.Show("Do you want to save changes", "Message", MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.Yes)
{
s = (PDVCollection)bindingSource1.DataSource;
s = s.Save();
}
else if (dialogResult == DialogResult.No)
{
this.DialogResult = DialogResult.OK;
}
}
}
Ok, here is final working solution, if anyone is looking for it.
public Form1()
{
InitializeComponent();
}
public PDVCollection s;
private void Form1_Load(object sender, EventArgs e)
{
bindingSource1.DataSource = PDVCollection.GetAll();
s = (StopaPDVCollection)bindingSource1.DataSource;
}
private void toolStripButton1_Click(object sender, EventArgs e)
s = s.Save();
bindingSource1.DataSource = s;
}
private void toolStripButton3_Click(object sender, EventArgs e)
{
if (dataGridView1.CurrentCell.RowIndex > -1)
{
PDV sel = (PDV)dataGridView1.CurrentRow.DataBoundItem;
s.Remove(sel);
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (s.IsDirty)
{
DialogResult dialogResult = MessageBox.Show("Do you want to save changes", "Message", "Poruka", MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.Yes)
{
s = (PDVCollection)bindingSource1.DataSource;
s = s.Save();
bindingSource1.DataSource = s;
}
else if (dialogResult == DialogResult.No)
{
this.DialogResult = DialogResult.OK;
}
}
}
}
I have a one issue in my window application, there are two form :login and main.
I have created Exit Button on both form and also coded of Exit Confirmation.
It works fine when we Press Exit Button message No on form 1. But We login to on form to
another form and second form Exit Button message button press No , and then back to return
form one and then click exit btton No ::::::it will display two times message PopUp of confirmation...............
Code
private void Btn_Exit_Click(object sender, EventArgs e)
{
DialogResult dr = MessageBox.Show("Do you want to exit.", "Message", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (dr == DialogResult.Yes)
{
Application.ExitThread();
} else
{ }
}
Plz there is any solution in c#............
Just code this.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Do you want to close this application?", "Exit", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.No)
{
e.Cancel = true;
}
}
In your case consider LoginForm and MainForm , Once you logged in you try to hide the LoginForm and show MainForm. Problem is when you try to close MainForm it will invoke the respective FormCloseEvent and once you chose to close, it automatically invoke parent form that is hiding in background, so it invokes LoginForm's FormCloseEvent. This is the reason for two time Popups.
To resolve this you need to trigger an event i.e whenever Child form is closed you need to raise a flag, so in your parent's FormCloseEvent you need to check for flag, if flag is true you no need to show the pop up.
private bool isMainFormClosed = false;
private void showMainForm()
{
// Hide the loginform UI.
this.Hide();
var mainForm = new MainForm();
// Creating close event for mainform, whenever close icon is clicked it will close the login form which is hiding in background.
mainForm.FormClosed += new FormClosedEventHandler(mainFormClosed);
// Show the mainform UI
mainForm.Show();
}
private void mainFormClosed(object sender, FormClosedEventArgs e)
{
this.isMainFormClosed = true;
this.Close();
}
private void loginFormClosing(object sender, FormClosingEventArgs e)
{
if(!this.isMainFormClosed)
{
DialogResult dialogResult = MessageBox.Show("Do you want to close the application",AppConstants.APPLICATION_NAME,
MessageBoxButtons.YesNo,MessageBoxIcon.Question);
if(dialogResult == DialogResult.No)
e.Cancel = true;
}
}
DialogResult is returned by dialogs after dismissal. It indicates which button was clicked on the dialog by the user.
Code
private void btnExit_Click(object sender, EventArgs e)
{
const string message = "Do you want to exit?";
const string caption = "EXIT";
var result = MessageBox.Show(message, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
Application.Exit();
}
else if (result == DialogResult.Yes)
{
this.Close();
}
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Do you want to close this application?", "Exit", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.No)
{
e.Cancel = true;
}
}