何时创建默认表单实例?

时间:2014-07-23 09:23:17

标签: vb.net winforms forms

在VB.NET中,表单实例的启动顺序和处理非常奇怪。当您引用表单(例如Form2.Textbox1.Text = "Foo")时,CLR会自动使用在后台创建的表单实例,并可以通过My.Forms.Form2直接访问。

我正在使用通过自定义Sub Main()启动的WinForms应用程序。这里通过调用Application.Run(frmMain)来运行应用程序。

由于我有多个需要初始化的表单,我想确切地知道真正的表单实例创建的位置。它们都是在Application.Run创建的,还是仅在我致电Form2.Show()时创建的?我的启动顺序现在如下:

  1. Sub Main()
  2. Sub Main()调用Application.Run(frmMain)
  3. frmMain.Load来电frmNotMain.Show()
  4. 我现在可以找到像My.Forms.frmNotMain = New frmNotMain这样的行,因此创建实例的位置并不明显。

    提前谢谢。

1 个答案:

答案 0 :(得分:3)

According to MSDN

  

当您通过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来明确这一点,但是使用默认实例,所有这些实际上都隐藏在表单工厂中。