您不想创建对表单的引用 - 这将(或可能)创建一个全新的表单。您想保留表单参考。
这是通过传递对表单的引用来完成的,但是谈论一个表单摆弄另一个表单上的控件是一个坏主意,因为它破坏了封装。但是表单是类(它在每个类的顶部都这样说),因此您可以添加 Properties 和 Methods(Sub 和/或 Functions)到方便来回传递信息。
方法一 - 传递表单引用
最简单的方法是在构造函数中传递其他表单需要的任何内容:
' form 1 / "main" form / form to return to
Dim frm As New Form6(Me)
frm.Show()
Me.Hide()
为了使其工作,您需要修改目标表单上的构造函数 (Sub New):
Private frmReturnTo As Form
Public Sub New(f As Form)
' This call is required by the designer.
InitializeComponent()
frmReturnTo = f
End Sub
在您熟悉它们之前,最好不要创建自己的构造函数。使用代码窗口顶部的下拉菜单:从左侧选择表单名称;从右侧选择新建。设计者向他们添加了必需的代码,这些代码不得更改。
不要在InitializeComponent() 调用之前添加任何代码,至少在您熟悉表单的生命周期之前。在运行之前,表单及其控件不存在。
返回“主”表单:
If frmReturnTo IsNot Nothing Then
frmReturnTo.Show()
End If
您可能希望删除一些标题栏按钮或将代码添加到表单Closing 事件以在用户通过系统菜单或按钮关闭时进行处理。
在表单必须拥有一些数据才能完成其工作的情况下,使用构造函数是理想的选择。
方法二 - 传递数据
这一切都很好,但是将 data 传递给另一个表单呢?您也可以使用构造函数。为了传递说,一个字符串,整数和一个Point:
' destination / second form:
Public Sub New(a As String, b As Int32, c As Point)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Label1.Text = a
Label2.Text = b.ToString
Label3.Text = c.ToString
End Sub
这样称呼它:
' method two: pass data you want to share in the ctor
Dim frm As New frmData("hello", 6, New Point(150, 550))
frm.Show()
结果:
方法三:属性
这很好,但是如果有大量数据,这种方式会变得很麻烦。另外,您可能希望更新调用/主窗体中的一些数据。为此,您可以在表单上创建Properties 来处理数据:
Public Property Label1Text As String
Get
Return Me.Label1.Text
End Get
Set(value As String)
Me.Label1.Text = value
End Set
End Property
不是使用私有变量作为支持字段,而是使用其中一个控件。该名称有些不尽人意,因为它公开了实现细节。因此,请使用描述数据表示内容的名称,而不是显示位置的名称。
Public Property SpecialValue As Integer
Get
Return Integer.Parse(Me.Label2.Text)
End Get
Set(value As Integer)
Me.Label2.Text = value.ToString
End Set
End Property
Public Property SomePoint As Point
Get
Dim data = Me.Label3.Text.Split(","c)
Return New Point(Convert.ToInt32(data(0)),
Convert.ToInt32(data(1))
)
End Get
Set(value As Point)
Me.Label3.Text = value.X.ToString & "," & value.Y.ToString
End Set
End Property
point 只是用来表明可以使用其他数据类型。从调用/原始/源表单设置这些值:
Using frm As New Form6
frm.Label1Text = "Ziggy"
frm.SpecialValue = 42
frm.SomePoint = New Point(111, 222)
frm.ShowDialog()
' do stuff here with any changes
Dim theint = frm.SpecialValue
End Using ' dispose of dialog
目标控件很可能是供用户编辑的文本框。 Property“包装器”允许您取回这些值,因此在本例中,使用了 Dialog。
方法四:方法
您还可以使用方法将数据传递给第二个/辅助表单。这里将传递一个List(of T) 集合。在子/显示表单中,添加了一个方法来接收它然后显示的数据。代表的任务是校对或查看过滤列表:
Public Sub UpdateDisplay(lst As List(Of SimpleItem), filter As String)
DataGridView1.DataSource = lst
Label1.Text = String.Format("{0} Total {1} Items", lst.Count, filter)
End Sub
在主/调用表单中:
' form level variable
Private frmDV As frmDataView
在其他地方...可能在 Click 事件中:
' myList is a simple list of items
' Users pick which color to filter on via a combo box
Dim filter As String
If cboListFilter.SelectedItem IsNot Nothing Then
'Dim frmDV As New frmDataView
If frmDV Is Nothing OrElse frmDV.IsDisposed Then
frmDV = New frmDataView
End If
filter = cboListFilter.SelectedItem.ToString()
' apply the filter
Dim tmpList = myList.Where(Function(w) w.Color = filter).ToList()
frmDV.UpdateDisplay(tmpList, filter)
frmDV.Show()
Else
Return
End If
结果:
使用基于 DataBased 的应用程序的修改版本可以允许您在另一个表单上以详细表单显示 DataGridView 数据的情况。您不需要让第二个窗体梯级 SQL 来添加或更新记录,然后主窗体运行另一个查询来“刷新”显示。如果DataSource 是由完全配置的DataAdapter 备份的DataTable,则传递DataTable 并使用它来添加、更改或删除子表单。数据将自动位于DataTable and DataGridView`中。
还有其他方法可以做到这一点,但它们通常都归结为将某些内容从 A 传递到 B。哪种方式“最好”取决于应用程序的功能、用例和数据的性质。没有一种正确的方法或最好的方法。
例如,Properties 和许多情况下的Functions 允许 B 表单关闭反馈循环。对于 DB 项,DataChanged 属性可能会告诉调用表单数据已添加或更改,以便表单知道使用 DataAdapter 更新数据库。