I would like to store some data about open MdiChildren to restore them when the application restarts.
But the MdiChildren property seems to empty on the ApplicationExit event.
Which event do I listen to to be able to get a list of open MdiChildren when user closes the main window?
try following code. It works for me. you can put additional loginc in If to check if any child window is visible ot not and if not then don't ask any question.
private void MDIParent1_FormClosing(object sender,
FormClosingEventArgs e)
{
if (MessageBox.Show("Close?",
AppDomain.CurrentDomain.ToString(), MessageBoxButtons.YesNo) ==
DialogResult.No)
{
e.Cancel = true;
}
}
Related
How do I go about changing what happens when a user clicks the close (red X) button in a Windows Forms application (in C#)? I want to add a simple DialogResult and Messagebox to ask user if he's sure about closing the form.
You should handle the FormClosing event on the Form class. In the handler, you are able to set the value of the CancelEventArgs.Cancel property to true to prevent closure of the form.
Example:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Close?", "Close", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
e.Cancel = true;
}
You can create the handler method by double-clicking the event in the Properties tab while the Windows Forms designer is open:
See https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.form.formclosing?view=windowsdesktop-6.0
I have a form that, upon user request, opens a child form, like so --
private void toolTrim_Click(object sender, EventArgs e)
{
Form form = new TrimOptions();
form.ShowDialog();
if (form.DialogResult == DialogResult.OK)
{
//code;
}
{
This child form has a button called btnOk and its property AcceptButton set to btnOk. This means that, when the Enter key is pressed in the child form, it's as if you had clicked on the Ok button, and this code executes.
private void btnOk_Click(object sender, EventArgs e)
{
Properties.Settings.Default.Save();
DialogResult = DialogResult.OK;
Close();
}
The problem is that, when the child form closes, the Enter key that was used to close the child form is captured by the DataGridView in the parent form.
private void filesDataGridView_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Return) //execution stops here if breakpointed
There's a legitimate use for that, but only when the DGV has focus, not when some child form of this form has focus.
So, how to prevent keystrokes in a child form from "bubbling up" to a parent form?
Following Steve's advice, I removed the Close(); having learned that setting DialogResult to any value other than None will close the window.
Following Hans Passant's advice to use KeyDown instead of KeyUp, I realized I had a mixture of KeyDowns and KeyUps. He was also correct, of course, that indeed the DGV had focus. I made them all KeyDowns, and my problem went away.
the other solution would be before opening modal you can disable the parent form once dialog is closed you can enable the parent form, so key up event does not fire.
I have started prototyping a C# MDI application and am running into an issue. It seems that when an MDIChild is open in the MDIParent I have to hit the close buttom on the parent multiple times to close the application. Each click on the close button closes one of the MDIChildren.
I suspected that it had to do with my MDIChildren's base form's on close method.
private void _AssetFormBase_FormClosing(object sender, FormClosingEventArgs e)
{
if(sender != this.MdiParent)
{
e.Cancel = true;
this.Hide();
}
}
Though my trick above does not seem to work. I assume that when the MDIParents close is called it in turn first calls all of its childrens close methods. So if the sender is the parents then instead of cancelling and hiding (to preserve the forms state), I would not do this and allow whatever normally happens to happen.
Any idea what the issue might be?
The sender is not what you think it is. Use e.CloseReason instead, you'll get CloseReason.MdiFormClosing. But don't test for that specific value, you also don't want to prevent the operating system from shutting down. Use:
private void _AssetFormBase_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
this.Hide();
}
}
Note that you'll also get UserClosing when you call Close() in your own code.
I'm working on a C# project. I need to do the following but I'm not really experienced and I can't find it on the Internet.
I want to do an action when the user clicks on the cross button (for closing one form). I mean, if the user clicks on the "X" button on the top right of the form I want to use a method that deletes one file.
I just want to know the code for noticing that the user clicked on the "X" (close) button. I hope you guys understand my question. Thank you so much!!
I don't think it's user friendly to delete something on closing a form (especially as the 'X' button is understood as the close button by everybody who uses a computer), but you can override the OnFormClosing method of a form. Something like this:
// this will also close the form
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
if (e.CloseReason == CloseReason.WindowsShutDown) return;
// Do some stuff here (delete the file or whatever)
}
If you want to alter the behavior so bad that the form won't close on pressing 'X', you could do sth like
protected override void OnFormClosing(FormClosingEventArgs e)
{
e.Cancel = true;
// some stuff here...
}
Which is very nasty IMO
You have to handle FormClosing event:
The FormClosing event occurs as the form is being closed. When a form
is closed, it is disposed, releasing all resources associated with the
form. If you cancel this event, the form remains opened. To cancel the
closure of a form, set the Cancel property of the FormClosingEventArgs
passed to your event handler to true.
This is the code in question:
private void FormAccounting_FormClosing(object sender, FormClosingEventArgs e)
{
Properties.Settings.Default.FormAccountingLocation = this.Location;
Properties.Settings.Default.Save();
if (IsEditing)
{
MessageBox.Show("Please save or cancel open transactions before closing the accounting window.", "Open Transactions", MessageBoxButtons.OK, MessageBoxIcon.Information);
e.Cancel = true;
}
}
I've added breakpoints to the e.Cancel = true; line to ensure it's being executed.
The form closes immediately after clicking Ok.
Here's the code that calls FormAccounting:
private void buttonAccounts_Click(object sender, EventArgs e)
{
FormAccounting NewFormAccounting = new FormAccounting();
NewFormAccounting.Show();
}
Canceling the form close event works to prevent:
User closing the form
Application.Exit from exiting the application
Code from calling Form.Close on the form
But it does not work to prevent:
User closing application's main form
Code calling Form.Dispose on the form
Code calling Form.Close on the application's main window
The last 3 cases don't even trigger the form close event on the non-main form, so the form goes away without a chance to cancel it. Perhaps your application is causing the form to first close in one of the first 3 ways, which triggers the event, and then in one of the second 3 ways (or something similar), which does not trigger the event and forces the form closed anyway.
Edit:
Add this function to your form's code and it will allow you to review in the debugger what the call stack looks like when your window is getting closed so you can see what is actually causing it:
protected override void DestroyHandle()
{
System.Diagnostics.Debugger.Break();
base.DestroyHandle();
}