我需要你的帮助来澄清表单是否与对象完全相同?
如果我从另一个对象obj1创建一个obj2对象。 obj2将在obj1处置。
然而形式并非如此。 查看案例&伪代码在下面给出。
我有三种形式; form1,form2&窗口2。
form1是启动表单。 form1将创建一个form2和from2将如何创建&使用每种形式的按钮显示form3。
如果我关闭form2,打开所有3个表单后,我可以在form1和form3中工作。
我的问题是即使form3是从form2创建的,为什么它不会在form2上关闭?
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
窗体2
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_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
frmMain.tsStatus.Text = "Form3 disposed"
End Sub
End Class
非常感谢任何帮助。
修改 谢谢大家的解决方案
很抱歉提及,我不是在寻找解决方案如何在form2关闭处理form3。
我感兴趣的是背后发生的事情......是否有可能从2创建的form3实例获得GC收集并且我得到内存错误。
因为我在我的实际应用程序中获得了保护内存访问异常,这个异常设计不合适,而且现在重构太大了。
我的问题是在哪里创建了form3实例?是在Form2实例中还是在其他地方。 因为我可以在form2处理后访问form3实例。我怀疑它是在其他地方创建的
答案 0 :(得分:1)
Dispose调用与您自己创建的新表单相关的表单上没有任何自动发生。
如果您希望表单自动处理它创建的表单,您必须自己添加代码才能执行此操作。找到设计器添加的.Dispose方法,并将其添加到那里,或者在表单上实现FormClosed事件。
form2“创建”form1并不会在两者之间形成任何关系。
答案 1 :(得分:1)
可选择自动处理。表格必须是“拥有”的表格。最简单的方法是使用Form.Show(owner)重载:
private void button1_Click(object sender, EventArgs e) {
new Form3().Show(this);
}
或者您可以使用Form.AddOwnedForm()方法执行此操作。请注意,这有副作用,拥有的表格始终显示在所有者面前。它将与业主一起最小化并恢复。如果您不想这样做,您可以明确跟踪表单的生命周期并自行处理:
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();
}
答案 2 :(得分:0)
如果我从另一个对象obj1创建一个obj2对象。 obj2将在obj1处置。
不一定。如果某个其他对象(例如obj3
)引用了obj2
,那么obj2
即使在obj1
被垃圾回收后仍会存在。
在这种情况下,窗口管理器引用了form3
,因此即使form2
是,也不会进行垃圾回收。
答案 3 :(得分:0)
您必须使用以Win32-Window-Handle作为参数的Form-Constructor。您可以将form2的引用传递给form3然后它可以按预期工作。
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
答案 4 :(得分:0)
如果您将表单变量更改为实例变量,并将其包含在Show方法中,它将起作用
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;
}
}
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);
}
}
答案 5 :(得分:0)
框架仍然保持着你的表单对象,直到它被关闭。您可以使用My.Application.OpenForms获取对它的引用。