I have two forms and form1 needs to get data from form2, i use a parameter in form2 constructor to gets form1's instance like this:
public form2(Form form1) {
this.f = form1;
}
and in form1:
Form form2 = new Form(this);
But it seem form1 destruct was called when i closed form1. my question is how can i avoid this problem?
EDIT: I have many typing mistakes in my question, i'm so sorry, fixed:
I have two forms and form2 needs to get data from form1, i use a parameter in form1 constructor to gets form1's instance like this:
private Form f;
public form2(Form form1) {
this.f = form1;
}
and in form1:
Form form2 = new Form(this);
But it seem form1 destructor was called when i closed form2. my question is how can i avoid this problem?
from MSDN:
When a form is closed, all resources created within the object are
closed and the form is disposed. You can prevent the closing of a form
at run time by handling the Closing event and setting the Cancel
property of the CancelEventArgs passed as a parameter to your event
handler.
As such, to prevent disposal of the resources, the only thing you can do is hide the form instead of closing it:
bool reallyClose;
protected override void OnClosing(CancelEventArgs e)
{
if (!reallyClose)
{
e.Cancel = true;
Hide();
}
base.OnClosing(e);
}
This will prevent the form being closed unless you manually set the reallyClose flag to true before closing the form.
You should make sure to close the form properly after you've finished using it.
Another option might be to decouple the data you need to retrieve from Form1 from the form itself.
In this case, form 1 cannot be destroyed until form2 is also closed. As long as form2 has a reference to form1, form1 will continue to exist. More likely, you are concerned with form1 being disposed. When form1 is closed, it will dispose itself. The object will still exist, but it will have released all its child controls and system objects such as window handles and drawing objects. Once a form has been disposed, it cannot be shown again, and all of it's controls will be inaccessible. If you try to use any of the visual components of a disposed form, it will throw an ObjectDisposedException. If you want to stop the form from being disposed, simply hide it rather than closing it. However, you should close it later once Form2 no longer needs it, otherwise it will stay around eating up memory and resources.
You should really factor whatever data you need out of both forms altogether, thereby avoiding the problem of coupled form constructors in the first place.
Related
I want to refresh an already opened form (form1) from another opened form's (form2) button_click(). In form1 I display the data saved by form2 and when form1 is already opened I want it to refresh if new data is saved on form2 in order to display it.
The problem is that I've tried iterating through `Application.Openforms`, but it turns out that it is read-only and I cannot access the form once found and I don't know how to access *form1* from *form2*, since I can't simply find it.
How can I access *form1* from *form2*?
Edit:
Form1 is actually opened from Form2.
The problem with Application.Openforms is that , as I've stated, a read-only list of forms already opened and I cant actually access the forms through it. They simply don't have the methods for it, I sugest you try using Application.OpenForms and look it up if you don't know how it works.
Also it's pointless to show what I've already tried because it includes Application.OpenForms, but for the sake of information:
FormCollection of = Application.OpenForms;
foreach (var f in of)
{
if (f.GetType().ToString() == "Kontrl_Doc.Visualizar")
{
f.Refresh();
}
}
When I click the button (button_click()) in Form2 it checks if Form1 is open or not. If Form1 isn't open it opens one and if it is than I'd like it to refresh it. Simultaneously, it closes Form2 and opens Form2 again, in order to reset is fields.
What I wan to do is, if the form1 is already opened , it form2 should tell it to refresh the already opened window with the form 1.
"Form1 is actually opened from Form2" - If this is the case, then just call Refresh using the form variable that you have in Form2. If necessary, make that a private field in the Form2 class or store it in an array for later use.
For example:
(Somewhere in Form2)
Form1 form1 = new Form1();
form1.Show();
(Inside the button click in Form2)
form1.Refresh();
you can use events. In form2 you place this code
public event Action ReloadForm1;
//on the place where you will reload form1
ReloadForm1();
and in form1 if you have opening form2:
form2.ReloadForm1 += Reload;
//outside method
void Reload()
{
this.Reload();
}
Create a void method in form1 and add the components u want to refresh maybe you want to reload a dropdown from db
public void Refresh()
{
...
}
then open a dialog of form2
catch the dialog result
I am developing a winforms application with the code below to open new form :
using (Form1 f = new Form1(textBoxJobCardNo.Text, tf, tfh))
{
// System.GC.Collect();
f.FormBorderStyle = FormBorderStyle.None;
f.Left = sc[1].Bounds.Left;
f.Top = sc[1].Bounds.Top;
f.Height = sc[1].Bounds.Height;
f.Width = sc[1].Bounds.Width;
f.StartPosition = FormStartPosition.Manual;
labelerror.Visible = false;
textBoxJobCardNo.Clear();
f.ShowDialog();
}
I am using ShowDialog() to open new form. In place of ShowDialog() I want to use Show() without removing using statement because the using statement helps me to free memory after form close. If I use Show() then it will not hold on after Show() and moves out of using scope, which will close the form.
When i am using using my ram usage is constant when i am trying to do it with show without using it increase 2 mb on every form open.
Can't i hold control in using like show dialog with show.
If you don't show the form modally (using ShowDialog()), by default, it'll be disposed on closing. This is what the MSDN says:
When a form is closed, all resources created within the object are closed and the form is disposed. You can prevent the closing of a form at run time by handling the Closing event and setting the Cancel property of the CancelEventArgs passed as a parameter to your event handler. If the form you are closing is the startup form of your application, your application ends.
The two conditions when a form is not disposed on Close is when (1) it is part of a multiple-document interface (MDI) application, and the form is not visible; and (2) you have displayed the form using ShowDialog. In these cases, you will need to call Dispose manually to mark all of the form's controls for garbage collection.
So there's no need to call Dispose() (or use a using block) if the form is not modal and not MDI, it'll be freed when closed.
That said, this is an implementation detail that might change (although at this point in time, it's unlikely that it will), and it should be safe to call Dispose() multiple times if you want.
Put this line of code in the FormClosed Eventhandler of the form
this.Dispose();
aka:
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
this.Dispose();
}
The using block does nothing more than call dispose() on the resource you specify after the block ended. If you handle Disposing your Resources yourself you dont have to use the using block and your Resources are freed the way you specify, in this example after the Form has been closed.
Edit:
protected override void OnFormClosed(FormClosedEventArgs e)
{
base.OnFormClosed(e);
this.Dispose();
}
Form.Show() should be called without a using block because it will return immediately after showing the form, so that the user can access the new form and all other forms that are present. In a using block the newly shown form would be destroyed immediately after creation because of the automatic Dispose() call at the end of the block.
Form.ShowDialog() returns much later: after the Modal form is closed, so this will work fine in a using block.
how do I check if a form is closed?
I want to reload a listview's items when I close another form.
What I'm doing is:
Form1 = form with ListView
Form2 = form with TextBoxes
Opening a new form.
Creating a new folder via a textbox.
When I press "Add" in Form2 I want to reload the "ListView" on Form1.
So how am I supposed to do this?
And sorry for my bad English :(.
The simplest answer is to make a public method on Form1, let's call it RefreshList() and in your button click event on Form2, you simply call Form1.RefreshList. Here's a quick sample:
Form 2:
public Form1 ParentForm { get; set; }
private void Button_Click(object Sender, EventArgs args) {
{
// After the rest of your handler
if(ParentForm != null)
ParentForm.RefreshList();
Close(); // Close Form2 here, we're done!
}
Form 1:
private void ShowForm2()
{
Form2 form2 = new Form2();
form2.ParentForm = this;
form2.Show();
}
public void RefreshList()
{
// do your refresh here
}
Initially you mention that you want to do this when Form2 closes, but then later you mention that you want to do it "When I press "Add" in Form2 I want to reload the "ListView" on Form1." As others have mentioned, you can use the Closed event, so I took this approach to address your second case.
In Form1, you can subscribe to From2's FormClosed event.
You can handle the form Closing event as the Closed Event is obsolete if you are using anything above dot net 1.1
You can handle the FormClosed event if you simply want to react to when a particular form is closed. If you want to take it a step further, there is a FormClosing event that you could also handle and even prevent the form from closing if need to.
Having Form1 add an event handler to Form2's FormClosing event is an excellent option. However, there is an even simpler solution if Form2 is a dialog window. In other words, if it's OK for Form1 to be effectively locked and disabled while Form2 is displayed, you can simply show Form2 as a dialog window. Dialog windows show synchronously, so you can simply update the list immediately after showing Form2 and it won't hit that list-updating code until after Form2 is closed. For instance:
form2.ShowDialog(this);
updateList();
I have a form Form1 from which I display Form2 as a modal form. From Form2 I do all sort of editing and deleting of different set of values which should be reflected in Form1 after closing Form2. So what I do is RePopulateControls_in_Form1() after closing Form2. Since RePopulateControls_in_Form1()is a long process, I want to execute that method only if some modification (edit,add, delete) happens in Form2 and not when Form2 is just opened and closed.
So this is what I try to do in Form1:
Form2 f = new Form2();
if (f.ShowDialog(this) == DialogResult.Something)
RePopulateControls_in_Form1()
And then in Form2 I do,
private void bntEdit()
{
//If Edit?
this.DialogResult = DialogResult.Something;
}
private void bntAdd()
{
//If Add?
this.DialogResult = DialogResult.Something;
}
private void bntDelete()
{
//If Delete?
this.DialogResult = DialogResult.Something;
}
But my problem is .Something. If it is anything other than .None, Form2 simply gets closed. I do not want Form2 to get simply closed by its own unless the user closes it.
If I do this:
//in Form1
private void Form1_Click()
{
Form2 f = new Form2();
if (f.ShowDialog(this) == DialogResult.None)
RePopulateControls_in_Form1()
}
//in Form2
private void Form2_SomeModification()
{
//If Modified?
this.DialogResult = DialogResult.None;
}
RePopulateControls_in_Form1() is not hit!
In short, in my program how can I tell the compiler to call RePopulateControls_in_Form1() only if values are modified in Form2?
Note: Repopulating is certainly required since the controls are dynamically created and a bit complex (actually what is created in Form2 is GUI controls and its labels etc).
Setting DialogResult on Form hides the form and returns from ShowDialog. If you want to delay that until the user performs some other action (such as closing the form) you should store that state as a member field and set DialogResult in a handler for Form.Closing.
Also, if you do want to dismiss the modal form on a button press, you can use the Button.DialogResult property instead of making a Button.Click handler.
A simple way might be not to use DialogResult at all but a dedicated property not interfering with the Form's behavior. - Then you should be able to program any logic you want.
I would use an event in Form 2. Fire that event when your Form2 is closing. Handling that event in Form1 would allow you to carry out any processing you want to. Further if needs be you could pass back some information from Form2 to Form1 in parameters to the event.
An alternative would be to set up a Global static variable - maybe just a bool. Then Form2 can set it to true or false depending on whether there are changes made. Form1 can read this when Form2 returns and if true carry out processing and set it back to false.
I have a MDI application with couple of windows. Is there any way to disable disposing form after it was closed by the user. I want to be able to reopen that form just by calling form.Show() method.
You could use Form.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 should do the same thing as you'd do with Form.Show()
You can save the values of the Form into a separate class before you call the Close() method of the form and load a new form which takes it's values from the saved class.
send the main form as a parameter to the child form, then the child form can reference the main form t any time
public Form MainForm = null;
public Sample(ref Form mainForm)
{
InitializeComponent();
MainForm = mainForm;
}
private void Sample_FormClosed(object sender, FormClosedEventArgs e)
{
MainForm.Show();
}