Windows form application sequential ShowDialog()s - c#

well I have a funny problem with closing dialog forms.
here is the problem:
I run application and open second form (through menu strip) as showdialog(); and then from second form open third form. When I open third form by button 1 and then close it everything is alright, but when I open the third form by button 2 and then close it, third form will be closed and then it closes the second form also. !!! In second form when I show a messageBox and close it also the second form will be closed.
here is my codes:
open second form from first form codes:
private void settingsToolMenu_Click(object sender, EventArgs e)
{
settingsForm s1 = new settingsForm(this);
s1.ShowDialog();
}
open third form from second by button 1 form codes:
private void addReportButton_Click(object sender, EventArgs e)
{
addReport a1 = new addReport(this);
a1.ShowDialog();
}
open third form from second by button 2 form codes:
private void editReportButton_Click(object sender, EventArgs e)
{
addReport a2 = new addReport(this);
a2.ShowDialog();
}
as you see there is no differences between button 1 and button 2
here is a video from application running.

Not sure what's happening out there, but there should be .Show() method, which runs a window in a different way including closing strategy. Try it out.

Try This
Instead of
addReport a2 = new addReport(this);
a2.ShowDialog();
Use
addReport a2 = new addReport();
a2.ShowDialog(this);
Then on click of Exit / Close button of dialog window
private void BtnExit_Click(object sender, EventArgs e)
{
this.Dispose();
}
Hope this will solve your issue.

I used this code and it worked. I have 3 forms, the first form is opened when running the app, the second form is opened with a button (can be menustrip, doesn't matter), then the third is opened like that too, after closing the third form the second form remains open.
FormN fm = new FormN();
fm.ShowDialog();
Use that piece of code in every method that is called from clicking on a button and it should work fine. Just change the "FormN" for whatever your forms are named. Also, if you need to pass any form's attributes into the next form you can do this:
Code at first form:
public string mytext; //Variable I want to use later, in Form2.
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
mytext = tb1.Text;
Form2 fm = new Form2(this);
fm.ShowDialog();
}
Notice how I save "tb1"'s (TextBox1) value in a variable before calling "fm.ShowDialog();", so I can use the TextBox1 value later inside the Form2.
Code at second form, having main form's variables (such as "mytext" value).
Form1 mfm;
public Form2(Form1 mainfm)
{
InitializeComponent();
mfm = mainfm;
}
public void button2_Click(object sender, EventArgs e)
{
//In this method I use the variable "mytext" wich is a Form1 attribute.
//You can see how I declare it in the first form's code (see above).
textBox1.Text = mfm.mytext;
}
With this you have created an object of your main form ("Form1 mfm;") with all the variables it contained before calling the second form, which can be used for the third form too.

in second form formClosing() event i wrote these codes:
private void settingsForm_FormClosing(object sender, FormClosingEventArgs e)
{
if(e.CloseReason != CloseReason.UserClosing)
{
e.Cancel = true;
}
}
and nothing can close the second form except user!

Related

Execute function on another, already open, form

I have a form with a datagridview inside of it.
When you doubleclick on a row from the datagridview, another form will open, which is basically a form where you can edit the data you just double-clicked.
There are a 3 buttons in this "edit" form, a delete, update and a return to main form button.
When finished with what you were supposed to do on this form, it closes.
My question is;
When this form closes, I want the data that is inside of the datagridview in the main form to refresh, how can I call that function on the main form from the edit form.
Keep in mind that I already have a reload function, let's say it's called refreshData();.
if you open the edit form as a modal window, the ShowDialog() call is blocking, so if you put the refreshData call after that it will execute after the edit form is closed:
var editForm = new EditForm(...);
var result = editForm.ShowDialog();
if (result == DialogResult.OK)
{
refreshData();
}
If you used .ShowDialog(), then just put the refresh function under this line of code.
The program will continue with the
private void cell1_DoubleClick(object sender, System.EventArgs e)
function.
So your code will look similair to this;
private void cell1_DoubleClick(object sender, System.EventArgs e)
{
//Your previous code ....
//The part where you open the EditForm
MyEditForm.ShowDialog();
//After it has been closed the program will continue to execute this function(if it has not been ended yet)
RefreshData();
//Since this function is running from your main form, the function RefreshData() will be executed on your main form aswell
}
No need to check some dialog results at all.
I think this will work:
Add a property DatagridviewForm of type DatagridviewForm (you have probably an other name/type) to AnotherForm. In the part where you call anotherForm.ShowDialog, add the following code:
anotherForm = new AnotherForm();
anotherForm.DatagridviewForm = this;
anotherForm.ShowDialog();
anotherForm.Dispose();
In the close handler of AnotherForm, update or refresh the data:
private void AnotherForm_FormClosed(object sender, FormClosedEventArgs e)
{
DatagridviewForm.refreshData();
}
You can access the data when the form is closing
Form MyEditForm;
private void cell1_DoubleClick(object sender, System.EventArgs e)
{
if (MyEditForm==null)
{
MyEditForm=new MyEditForm();
MyEditForm.FormClosing += refreshData;
}
MyEditForm.ShowDialog();
}
private void refreshData(object sender, EventArgs e)
{
var myDataObj=MyEditForm.getData();
}

Closing multiple windows form with single click

I want to close two forms at the same time. I have one main form that starts with program. when user click button, the main form will hide and other form will pop up. on the second form if user click "back to main " button, it should hide second form and show main form. But the problem is if user tries to close the second form it should close the main form as well. How can i close the main form as well
I would just use the Application.Exit() for what is requested by this thread.
Application.Exit();
UPDATE: corrected
I had said this will not call the form closing events but in documentation it does actually call it here is a link to the documentation
http://msdn.microsoft.com/en-us/library/ms157894(v=vs.110).aspx
It was better if you specified what codes you wrote for going back to main form, so I could help you by changing your codes. But now because I don't know how you did it, I have to write codes for both of those tasks.
It can be possible using a Boolean variable to do what you want. Follow bellow codes:
public partial class MainForm : Form
{
//"Click" event of the button that should opens the second form:
private void goToSecondForm_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(); //Or you can write it out of this method.
this.Hide(); //Hides the main form.
f2.ShowDialog(); // Shows the second form.
this.Show(); // Shows the main form again, after closing the second form using your own button.
}
}
public partial class Form2 : Form
{
bool selfClose = false; //False shows that user closed the second form by default button and true shows that user closed it by your own button.
//"Click" event of the button that should closes just the second form and returns user to the main form:
private void ownCloseButton_Click(object sender, EventArgs e)
{
selfClose = true; //Means user clicked on your own button.
this.Close(); //So the program closes the second form and runs f2_FormClosed method, but because selfClose became true here, happened nothing there and program will go back to goToSecondForm_Click method in the main form and will run this.Show() .
}
//"FormClosed" event of the second form :
//Whether user clicked on your own button or on the default one, this method will run.
private void f2_FormClosed(object sender, FormClosedEventArgs e)
{
if (!selfClose) //It means user didn't click on your own button and both of forms must be closed .
Application.Exit(); //So the program closes all of forms (actually closes the program) and couldn't access to any other commands (including this.Show() in goToSecondForm_Click method).
}
}
As others have said, you need to somehow call .Close() on the main form when your child form is closed. However, as you've pointed out, you don't have a reference to the main form automatically in your child form! That leaves you with a few options.
1. Exit the application immediately.
This is done by calling Application.Exit(); in your child form's "back to main" button's click event handler. It will immediately close all forms, which might simply be what you want.
// .. ChildForm code ..
void OnBackToMainClicked(object sender, EventArgs e)
{
Application.Exit();
}
2. Pass a reference to the main form to the child form.
This is probably the most common way to solve this problem in general. When you create your child form in your main form, you'll need to pass a reference as follows:
// .. MainForm code ..
void OnGoToChildForm(object sender, EventArgs e)
{
var childForm = new ChildForm(this);
childForm.Show();
}
// .. ChildForm code ..
private MainForm mainForm; // This is where the child form will keep a reference to
// the main form that you can use later
public ChildForm(MainForm mainForm)
{
// This is the child form's constructor that we called above,
// and it's where we'll save the reference to the main form
this.mainForm = mainForm;
}
// This also needs to be the event handler for the close event
void OnBackToMainClicked(object sender, EventArgs e)
{
this.Close();
mainForm.Close();
}
3. Add an event handler on the child form's FormClosed event. This is a safe way to solve the problem if you are concerned about keeping your main application logic under the control of the main form. It's similar to the solution suggested by Lamloumi above, but it's all done in the main form's code.
// .. MainForm code ..
void OnGoToChildForm(object sender, EventArgs e)
{
var childForm = new ChildForm(this);
childForm.FormClosed += new FormClosedEventHandler(SecondForm_FormClosed);
childForm.Show();
}
void SecondForm_FormClosed(object sender, EventArgs e)
{
// Perform any final cleanup logic here.
this.Close();
}
Form1 _FirstForm = New Form1();
Form2 _SecondForm = New Form2();
MainForm _MainForm = new MainForm();
_FirstForm.Close();
_SecondForm.Close();
_MainForm.Show();
Normally , in the Home form you have some ting like this :
SecondForm second= new SecondForm ();
second.Show();
this.Hide();
In the SecondForm you must ovveride the event of closure like this :
public class SecondForm :Form{
public SecondForm()
{
InitializeComponent();
this.FormClosed += new FormClosedEventHandler(SecondForm_FormClosed);
}
void SecondForm_FormClosed(object sender, FormClosedEventArgs e)
{
Application.Exit();
}
}
To be sure that your application is closed after you close the form. because the Home from is still active and hidden if you don't.
use this in Form2
private void button1_Click(object sender, EventArgs e)
{
Form1.FromHandle(this.Handle);
}
There Handle are the same now ;
hope this work.

Hiding a form, switch to a second form, close second form and unhide first form

I've looked at all the suggested answers and nothing seems to fit what I'm looking for. I want to call a second form from my main form, hide my main form while the second form is active, and then unhide the main form when the second form closes. Basically I want to "toggle" between the two forms.
So far I have:
In my main form:
private void countClick(object sender, EventArgs e)
{
this.Hide();
subForm myNewForm = new subForm();
myNewForm.ShowDialog();
}
and in my second form I have:
private void totalClick(object sender, EventArgs e)
{
this.Close();
}
How do I get the main form to show?
ShowDialog opens your secondary Form as Modal Dialog, meaning that the MainForm's code execution will stop at that point and your secondary Form will have the focus. so all that you need to do is put a this.Show after your ShowDialog call.
From above link:
You can use this method to display a modal dialog box in your application. When this method is called, the code following it is not executed until after the dialog box is closed.
private void countClick(object sender, EventArgs e)
{
this.Hide();
subForm myNewForm = new subForm();
myNewForm.ShowDialog();
this.Show();
}
Let's say in Form1 you click a Button to show Form2
Form2 frm2 = new Form2();
frm2.Activated += new EventHandler(frm2_Activated); // Handler when the form is activated
frm2.FormClosed += new FormClosedEventHandler(frm2_FormClosed); // Hander when the form is closed
frm2.Show();
Now, this one is when the Form2 is shown or is Activated you hide the calling form, in this case the Form1
private void frm2_Activated(object sender, EventArgs e)
{
this.Hide(); // Hides Form1 but it is till in Memory
}
Then when Form2 is Closed it will Unhide Form1.
private void frm2_FormClosed(object sender, FormClosedEventArgs e)
{
this.Show(); // Unhide Form1
}
This is difficult to do correctly. The issue is that you must avoid having no window at all that can get the focus. The Windows window manager will be forced to find another window to give the focus to. That will be a window of another application. Your window will disappear behind it.
That's already the case in your existing code snippet, you are hiding your main window before showing the dialog. That usually turns out okay, except when the dialog is slow to create. It will definitely happen when the dialog is closed.
So what you need to do is hide your window after you display the dialog and show it again before the dialog closes. That requires tricks. They look like this:
private void countClick(object sender, EventArgs e)
{
this.BeginInvoke(new Action(() => this.Hide()));
using (var dlg = new subForm()) {
dlg.FormClosing += (s, fcea) => { if (!fcea.Cancel) this.Show(); };
if (dlg.ShowDialog() == DialogResult.OK) {
// etc...
}
}
}
The BeginInvoke() call is a trick to get code to run after the ShowDialog() method runs. Thus ensuring your window is hidden after the dialog window is shown. The FormClosing event of the dialog is used to get the window to be visible again just before the dialog closes.
You need to find some way to pass a reference to the main form to the second form click event handler.
You can do this either by setting the form as a member variable of the second form class or pass it via the event arguments.
If you are working in the same namespace, you have the context, using mainform or the name you gave the "main form", try:
mainform.show();

How to reload form in c# when button submit in another form is click?

I have a combo box in my C# which is place in form named frmMain which is automatically fill when I add (using button button1_Click) a product in my settings form named frmSettings. When I click the button button1_Click I want to reload the frmMain for the new added product will be visible.
I tried using
frmMain main = new frmMain();
main.Close();
main.Show();
I know this code is so funny but it didn't work. :D
This is windows form!
EDIT
Please see this image of my program for better understanding.
This is my frmMain
Here is what my settings frmSettings form look like. So, as you can see when I click the submit button I want to make the frmMain to reload so that the updated value which I added to the settings will be visible to frmMain comboBox.
Update: Since you changed your question here is the updated version to update your products
This is your products form:
private frmMain main;
public frmSettings(frmMain mainForm)
{
main = mainForm;
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
main.AddProduct(textBox1.Text);
}
It will need the mainform in the constructor to pass the data to it.
And the main form:
private frmSettings settings;
private List<string> products = new List<string>();
public frmMain()
{
InitializeComponent();
//load products from somewhere
}
private void button1_Click(object sender, EventArgs e)
{
if (settings == null)
{
settings = new frmSettings(this);
}
settings.Show();
}
private void UpdateForm()
{
comboBoxProducts.Items.Clear();
comboBoxProducts.Items.AddRange(products.ToArray());
//Other updates
}
public void AddProduct(string product)
{
products.Add(product);
UpdateForm();
}
You then can call UpdateForm() from everywhere on you form, another button for example.
This example uses just a local variable to store your products. There are also missing certain checks for adding a product, but I guess you get the idea...
this.Close();
frmMain main = new frmMain();
main.Show();
There is no such built in method to set all your values as you desire. As i mentioned in the comment that you should create a method with your required settings of all controls, here is the sample code:
private void ReloadForm()
{
comboBox.ResetText();
dataGridView.Update();
//and how many controls or settings you want, just add them here
}
private void button1_Click(object sender, EventArgs e)
{
ReloadForm(); //and call that method on your button click
}
Try out this code.
this.Refresh();
Application.Doevents();
this.Refresh();
Refresh();
this.Hide();
frmScholars ss = new frmScholars();
ss.Show();
you want to Invalidate the form
http://msdn.microsoft.com/en-us/library/598t492a.aspx
IF you are looking to refresh page from usercontrol .Here is expample where i amrefreshing form from usercontrol
Find the form in which this reload button is.
Then Call invalidiate tab control and refresh it.
Dim myForm As Form = btnAuthorise.FindForm()
For Each c As Control In myForm.Controls
If c.Name = "tabControlName" Then
DirectCast(c, System.Windows.Forms.TabControl).Invalidate()
DirectCast(c, System.Windows.Forms.TabControl).Refresh() 'force the call to the drawitem event
End If
Next
Not required reload for entire form. Just create a function for form initialise.
you can call this function any time. This will refresh the form.
private void acc_Load(object sender, EventArgs e)
{
form_Load();
}
public void form_Load()
{
// write form initialise codes example listView1.Clear();...
}
private void button1_Click(object sender, EventArgs e) //edit account
{
//Do something then refresh form
form_Load();
}
If you want to automatically update the value of the other form when you click the button from another one you can use timer control. Just set the timer to 0.5s in order to update the form fast
I think that, by calling the frmMain_load(sender,e) when you are clicking the button should reload the form.
You may also try to Invalidate() the form just like #Nahum said.

How to open recently closed or hide form

I've researched thoroughly but still i cant find the best solution for this..
I have a 3 buttons, BACK - HOME - FORWARD ..
This is just like the buttons on the upper left of browser .. and im trying to do this on a form..
what i have is this ..
the back button code is
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
}
// simply hiding the form .. so that the previous form will be shown..
the home button code is this..
private void button2_Click(object sender, EventArgs e)
{
for (int i = Application.OpenForms.Count - 1; i >= 0; i--)
{
if (Application.OpenForms[i].Name != "HomePage")
Application.OpenForms[i].Close();
}
}
// this will show the HomePage form and close other forms whos name is not "HomePage"
the Problem is when i press the Back Button , im hiding it .. how can a button will re open a previously closed or hided form ?
I hope you can Help me! Thanks!
private void button3_Click(object sender, EventArgs e)
{
???????
}
You would need to store a reference to the form that you wish to open again.
There are a couple of options to do this, but if you simply wanted to allow the user to go "Forward" once, you could just store a reference to the form like so:
internal class MyHistory {
internal static Form LastForm;
}
// ........
private void button1_Click(object sender, EventArgs e)
{
MyHistory.LastForm = this;
this.Hide();
}
// ........
private void button3_Click(object sender, EventArgs e)
{
MyHistory.LastForm.Show();
}
Of course, you could maintain a full stack of history items and traverse back/forwards through them if you wanted to be more comprehensive than this.
Note that, if you .Close() your form, you won't be able to reopen it as the reference will be disposed of once it is closed. This method would only work if you were to .Hide() it, which keeps the form instance valid, just hides the form from the user's view.
you could use a form list which holds all initialized forms. that way you can hide, show, add and remove forms dynamically.
List<Form> lstForms = new List<Form>();
then when you add a form:
Form newForm = new Form();
lstForms.Add(newForm);
Hiding a Form:
lstForms(x).Hide(); //x = index of Form you want to hide
Showing a Form
lstForms(x).Show(); //x = index of Form you want to hide
Removing a Form (when closing it for example)
lstForms.RemoveAt(x);
that way you can dynamically work with forms and it is much easier to keep an overview if you have many forms...

Categories