在VB.NET中,表单实例的启动顺序和处理非常奇怪。当您引用表单(例如Form2.Textbox1.Text = "Foo"
)时,CLR会自动使用在后台创建的表单实例,并可以通过My.Forms.Form2
直接访问。
我正在使用通过自定义Sub Main()
启动的WinForms应用程序。这里通过调用Application.Run(frmMain)
来运行应用程序。
由于我有多个需要初始化的表单,我想确切地知道真正的表单实例创建的位置。它们都是在Application.Run
创建的,还是仅在我致电Form2.Show()
时创建的?我的启动顺序现在如下:
Application.Run(frmMain)
frmMain.Load
来电frmNotMain.Show()
我现在可以找到像My.Forms.frmNotMain = New frmNotMain
这样的行,因此创建实例的位置并不明显。
提前谢谢。
答案 0 :(得分:3)
当您通过My.Forms.Form1访问Form时,工厂方法将检查Form1的实例是否已打开。如果是,则返回该实例。否则,将创建并返回Form1的实例。
所以基本上它是在显示之前创建的并且Sub New
被调用(不是在某处创建并保持到需要之前)。该链接包含此代码,显示它如何创建这些默认实例:
'Code ... generated by the compiler
Public m_Form1 As Form1
Public Property Form1() As Form1
Get
m_Form1 = Create__Instance__ (Of Form1)(m_Form1)
Return m_Form1
End Get
Set(ByVal Value As Form1)
If Value Is m_Form1
Return
End If
If Not Value Is Nothing Then
Throw New ArgumentException("Property can only be set to Nothing.")
End If
Dispose__Instance__ (Of Form1)(m_Form1)
End Set
End Property
但是,您正在讨论默认("奇怪的")实例方法,这种方法一开始是不明智的。这主要是为了提供与VB6类型代码的兼容性,你只需要myForm.Show()
来实例并显示一个表单(可能对于那些并不真正了解实例化或OOP的修补程序)。
表单是类,应该通过显式创建实例来处理;所以,一般来说:
Dim frm As New frmMain ' NEW creates the instance
frm.Show
您可以在表单InitializeComponent
中的Sub New
上设置断点,以查看它何时被调用。要创建对它的全局引用,就像使用任何其他类一样:
Friend frmMain As MainForm ' no instance yet
Friend myMain As MainClass
Public Sub Main
' do this before any forms are created
Application.EnableVisualStyles()
myMain = New MainClass()
myMain.DoStuff()
frmMain = New MainForm() ' instanced (NEW)
Application.Run(frmMain)
End Sub
同样地:
Dim frm2 = New frmNotMain ' declare and instance
' short for:
Dim frm2 As frmNotMain ' declare frm2
frm2 = New frmNotMain ' create instance
frm2.Show
在所有情况下,当您使用Sub New
运算符创建新表单时,将调用表单的New
。 VB尝试通过重复使用New
来明确这一点,但是使用默认实例,所有这些实际上都隐藏在表单工厂中。