I have a class with several functions, within all of these functions I have a try catch and in a catch I start a new form to show the error. Like this:
Program.erro = exception.ToString();
Error NewError = new Error();
Error.ShowDialog();
But I need to be able to close the current form FormUpdate as an example whenever I close the error form.
I've put this line of code in the error's FormClosed event:
UpdateOrca.Update.ActiveForm.Close();
"Update" is the open form that needs to be closed.
You could just make use of the using statement and then when your error dialog has been closed, the rest of the code will execute.
using (Error NewError = new Error())
{
NewError.ShowDialog()
}
this.close();
You can then remove the code that you have placed in NewError's closing event.
As you can see in that SO question creating close event of the child form in main form, and calling this.close() inside it will solve the problem.
You should pass the calling form instance to the dialog form. .NET allows you identify the owner form of the openning form.
For example; You can open a popup like;
Dialog frmDialog = new Dialog();
frmDialog.ShowDialog(this);
Then; in the popup form you can listen the form_closing event like;
private void Dialog_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.Owner != null)
this.Owner.Close();
}
Hope it helps.
Related
I am trying to make one windows application which contains two forms. In form1(Parent) i created one button for open second form. On that button click event i want to close form1(parent) form and open form2(child) without closing form2, but when i am press that button both forms are closed so how can I do it?
Rather than using .Close() consider using .Hide() on your parent form, this shouldn't dispose of it but rather have it hidden.
Note that exiting out of your Child form means your application won't exit. To circumvent this you should consider subscribing to the OnFormClosed event to handle the form closure.
If you look in "Program.cs" there is a form to start with.
When this form is closed, the application is terminated.
enter image description here
It should be used as a way to hide the startup form.
Even if the child form is closed with the start form hidden, the program does not end.
As #Ae774 said, you need to handle it separately.
If you want to close form1(parent) form and open form2(child) form without closing form2 by click the button, you can refer to the following code:
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
Hide();
f2.ShowDialog();
Close();
}
If you want to open the parent form after the child form is closed, you can refer to this code:
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
Hide();
f2.ShowDialog();
Show();
}
Here is the test result
On the click of a button (that's in the main form), I show a (second) form that does some parsing (decompress, extract, get information, etc) of an archive file. After this process is done, I close the second (parsing) form and show another (third) form that contains the parsed information from the archive.
Click callback looks like this:
private void ParseInputBackupButton_Click(object sender, EventArgs e)
{
Form PBF = new ParseBackupForm();
Form CBF = new CreateBackupForm();
PBF.FormClosed += delegate
{
CBF.ShowDialog();
};
PBF.ShowDialog();
}
and the second form:
private void ParseBackupForm_Load(object sender, EventArgs e)
{
new Thread((ThreadStart)delegate
{
// parse and update form
this.Invoke((MethodInvoker)delegate
{
this.Close();
});
}).Start();
}
The problem is when the third form (CreateBackupForm) appears, the second form (ParseBackupForm) doesn't close. They both appear. If I don't show the third form, the second form closes.
What am I doing wrong?
As you are calling ShowDialog on both windows, couldn't you just call them one after the other?
i.e.
PBF.ShowDialog();
CBF.ShowDialog();
The second call will not be made until the PBG dialog has closed.
Edit: The reason why the second form doesn't close is that the you are subscribing to an event raised by the form as it closes, then within that delegate calling ShowDialog which blocks the form from actually closing.
As far as I can remember .ShowDialog() is a blocking method, so would stop the other form from completing its close method until that form is also closed?
Pretty sure you can use .Show() to just make a form visible without blocking?
You could BeginInvoke the call of CBF.ShowDialog();, thus not blocking the completion of the FormClosed callback method and the closing of the PBF form.
Is it possible to detect a form closing from another form.
For example.
If I had a mainForm that opens subForm, can I detect within the mainForm that the subForm has closed and execute code?
I understand I could create an event handler within the subForm, but this is not really what I'm after because what I'm about to do after the subForm closes, is within the mainForm (changes to mainForm).
The FormClosed event is public, so you can create a handler from the main form.
//Inside main Form. Click button to open new form
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.FormClosed += F2_FormClosed;
f2.Show();
}
private void F2_FormClosed(object sender, FormClosedEventArgs e)
{
MessageBox.Show("Form was closed");
}
Take a look at the public FormClosedEvent. Since the modifier is public, you're able to do something like the following example:
SubForm subForm = new SubForm();
subForm.FormClosed += delegate
{
MessageBox.Show("subForm has closed");
};
subForm.ShowDialog();
The above example creates a new form (of type SubForm), adds a new event handler to display a message box telling the user that the form has closed, and finally uses the ShowDialog() method which will prevent the user accessing the main form until the sub form has been closed.
The usual case for this is a "Modal Dialog" (like Message Box and its Family).
Every form can be opened as Modal Dialog, by using ShowDialog() isntead of Show().
Otherwise the event way is the only way.
I'm using visual studio 2010
frmMain has a "Register" button which calls another form newReg
This is the code for the button in frmMain that calls the second form. The problem is that the MessageBox("So Far So Good") never gets called. The dialogResult doesnt seem to be recognized.
private void btnRegisterNew_Click(object sender, EventArgs e)
{
// newReg Constructor Call
newReg = new frmRegisterNew();
// show form
newReg.Show();
if (newReg.DialogResult.Equals(DialogResult.OK))
{
MessageBox.Show ("So Far So Good");
}
}
The second form has some fields to fill in and a button "register". I've set the dialogResult of this button to 'ok' in the properties window and also, I think, in the code. When the "register" button in the second form is clicked it checks the input, tries to update a database and closes if successful. Here is that bit of code:
dbConnection db = new dbConnection();
db.dbConnect();
if (db.dbRegisterVehicle(txtNewReg.Text, txtNewMake.Text, txtNewModel.Text, txtNewColour.Text, OwnerID))
{
// if insert worked close
this.DialogResult = DialogResult.OK;
this.Close();
}
db.dbDisconnect();
I'm sure what to try, or what I might be over looking.
Use ShowDialog
newReg = new frmRegisterNew();
var dialogResult = newReg.ShowDialog();
if(dialogResult==DialogResult.OK)
{
....
}
The ShowDialog method is a good way to go but be aware of the differences between Show and ShowDialog. The latter will be modal which means that you can't access your original form until the new form is closed. This is why it blocks the check and may or may not be what you want.
When you call Show, it doesn't block, so that's why your code was immediately checking to see if the DialogResult was equal to OK (it wasn't equal to OK because your new form had barely opened by the time the check was made).
The alternative to using ShowDialog, if you want to use Show, is to handle the new form's closed event.
frmRegisterNew newReg = new frmRegisterNew();
newReg.FormClosed += (s, o) =>
{
if (newReg.DialogResult == DialogResult.OK)
{
MessageBox.Show ("So Far So Good");
}
};
newReg.Show();
This means that your code will continue to work and your new form will not be modal, but when the new form it closed, the FormClosed event handler will be fired. Don't worry if you're not familiar with the event handler notation above (they're called anonymous methods) but you can still use the event handler as normal.
newReg.FormClosed += new FormClosedEventHandler(newReg_FormClosed);
void newReg_FormClosed(object sender, FormClosedEventArgs e)
{
MessageBox.Show ("So Far So Good");
}
Try instantiating the DialogResult class and using it this way:
DialogResult dr = new DialogResult();
newReg = new frmRegisterNew();
dr = frmResgisterNew.ShowDialog();
if ( dr == DialogResult.OK )
//Take an action here.
Form.Show() is non-blocking and will return very quickly. Your check on newReg.DialogResult.Equals(DialogResult.OK)) will therefore occur before the user has had a chance to press the button. Furthermore, note this warning about closing the window:
If a Form is displayed as a modeless window, the value returned by the DialogResult property might not return a value assigned to the form because the form's resources are automatically released when the form is closed.
(via the Form.DialogResult Property msdn library page)
You can either call From.ShowDialog() or, if you need to keep interaction on the main form, pass a delegate for the other form to call when it's completed.
Edit: A couple of points to keep in mind:
In addition to the warning above about closing the form, you have to be careful about trying to access the contents from a method dispatched from newReg's message loop (including the function that called Close()) after it's been disposed.
If you end up using ShowDialog() instead of Show(), however, this.Close() will not dispose the form. In fact, it essentially does nothing since setting DialogResult to anything other than None will automatically hide the form. If you need deterministic clean-up (presumably why you're calling Close() in the first place), you should call newReg.Dispose() after you're done with it in btnRegisterNew_Click. Otherwise, the form will be disposed at some unpredictable time in the future (provided your application doesn't end abnormally in the interim).
If you use an anonymous function as mentioned by keyboardP, be aware that it can get hard to debug when something goes wrong (especially if you're relatively new to the language and framework).
Scenario
I have a C# WinForms application with a main form. I also have a button on this main form, that, when clicked, creates and displays a new form.
The problem....
...Is that I cannot click on anything on the main form when the new form is open.
The Question
How do I solve this? Is it possible to use both forms simultaneously?
Code To Launch New Form
private void barBtnStatsMonitor_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
//XtraMessageBox.Show("This Feature Has Not Been Fully Implemented Yet!");
using (StatsMonitorForm frm = new StatsMonitorForm())
{
if (frm.ShowDialog() == DialogResult.OK)
{
}
}
}
ShowDialog() opens a modal dialog.
Show() opens non-modal.
Try frm.Show instead of ShowDialog. ShowDialog opens the new form as a modal dialog so you cannot access the base form until you close this one.
when closing the main form its like closing the app...
so a suggestion would be, disable the main form close button when there are child forms open... and just enable it again when there are no child forms open...
or create a global variable(a bool perhaps), that when a child form is open.. its set to true... so when pressing the close button on the main form... it checks this variable if its true it prompts to save.. else it just closes...
ShowDialog() displays the form in MODAL mode which means you must close new form opened.
private void barBtnStatsMonitor_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
//XtraMessageBox.Show("This Feature Has Not Been Fully Implemented Yet!");
using (StatsMonitorForm frm = new StatsMonitorForm())
{
frm.Show();
//do some work here to get the dialog result some other way..
}
}