开发者

Even though form3 is created from form2, why it is not disposed on form2 close?

开发者 https://www.devze.com 2022-12-13 16:39 出处:网络
I need your help to clarify whether form work exactly like object? If I create an object,obj2, from another object,obj1. the obj2 will be disposed on obj1 dispose.

I need your help to clarify whether form work exactly like object?

If I create an object,obj2, from another object,obj1. the obj2 will be disposed on obj1 dispose.

However it is not so with forms. check out the case & pseudo code give below.

I have three forms; form1, form2 & form2.

form1 is the startup form. form1 will create &s how a form2 and from2 will create & show form3 using a button in each form.

if I close form2, after opening all the 3 forms, I am able to work in form1 and form3.

my question is even though form3 is created from form2, why it is not disposed on form2 close?

Form1


Public Class Form1
Private Sub cmdOpenForm2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdOpenForm2.Click
  Dim frm As New Form2
  With frm
   ''/.MdiParent = frmMain
   .Show()
   .BringToFront()
  End With
End Sub

 Private Sub Form1_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
  ''//frmMain.tsStatus.Text = "Form1 disposed"
 End Sub
End Class

Form2


Public Class Form2
 Private Sub cmdRandomColor_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRandomColor.Click
  Randomize()
  Label1.ForeColor = Color.FromArgb(Rnd() * 255, Rnd() * 255, Rnd() * 255, Rnd() * 255)
 End Sub

 Private Sub Form2_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
  frmMain.tsStatus.Text = "Form2 disposed"
 End Sub

 Private Sub cmdOpenForm3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdOpenForm3.Click
  Dim frm As New Form3
  With frm
   ''//.MdiParent = frmMain
   .Show()
   .BringToFront()
  End With
 End Sub
 End Class

Form3


Public Class Form3
 Private Sub cmdRandomColor_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRandomColor.Click
  Randomize()
  Label1.ForeColor = Color.FromArgb(Rnd() * 255, Rnd() * 255, Rnd() * 255, Rnd() * 255)
 End Sub

 Private Sub Form3_Dis开发者_C百科posed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
  frmMain.tsStatus.Text = "Form3 disposed"
 End Sub
End Class

Any Help will be greatly appreciated.

EDIT thank you all for the solution

Sorry to mention, I am not looking for a solution how to do dispose form3 on form2 close.

my interest is what is happening behind... Is there any possibility that form3 instance created from2 get GC collect and i get a memory error.

since i am getting protect memory access exception in my real application, which is not properly designed, and it too big to refactor now.

my question is where the form3 instance created? Is it in Form2 instance or somewhere else. since i can able to access form3 instance after form2 disposed. i doubt it is created in somewhere else


There's nothing automatic happening in Dispose calls on forms related to new forms you create yourselves.

If you want a form to automatically dispose of a form it creates, you have to add code yourself to do this. Either find the .Dispose method added by the designer, and add it there, or implement the FormClosed event on the form.

That form2 "creates" form1 does not make any kind of relationship between the two.


Automatic disposal is available as an option. The form must be an "owned" form. The easiest way to do this is to use the Form.Show(owner) overload:

private void button1_Click(object sender, EventArgs e) {
  new Form3().Show(this);
}

Or you can do it afterwards with the Form.AddOwnedForm() method. Beware that this has side-effects, an owned form is always shown in front of the owner. And it will get minimized and restored along with the owner. If you don't want this, you can keep explicit track of the lifetime of the form and dispose it yourself:

private Form3 mForm3;

private void button1_Click(object sender, EventArgs e) {
  if (mForm3 == null) {
    mForm3 = new Form3();
    mForm3.FormClosed += (s, ea) => mForm3 = null;
    mForm3.Show();
  }
  else {
    mForm3.WindowState = FormWindowState.Normal;
    mForm3.Focus();
  }
}

protected override void OnFormClosed(FormClosedEventArgs e) {
  if (mForm3 != null) mForm3.Dispose();
}


The framework is still holding on to your form object, until it gets closed. You can get a reference to it using My.Application.OpenForms.


If i create an object,obj2, from another object,obj1. the obj2 will be disposed on obj1 dispose.

Not necessarily. If some other object, say obj3 has a reference to obj2, then obj2 will stick around even after obj1 has been garbage collected.

In this case, the window manager has a reference to form3, so it won't be garbage collected even when form2 is.


You have to use the Form-Constructor that takes a Win32-Window-Handle as a parameter. You can pass a reference of form2 to form3 then and it works as you expected.

Private Sub cmdOpenForm2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdOpenForm2.Click
  Dim frm As New Form2(Me)
  With frm
   .Show()
   .BringToFront()
  End With
End Sub


If you change the form variables to instance variables, and include this in the Show method, it will work

Code for Form1

public partial class Form1 : Form
    {
        Form2 f;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            f = new Form2();
            f.Show(this);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            f.Close();
            f = null;
        }
    }

Code for Form2

public partial class Form2 : Form
    {
        Form3 f;
        public Form2()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            f = new Form3();
            f.Show(this);
        }
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号