【问题标题】:How to pass a form, object or data to a second form如何将表单、对象或数据传递给第二个表单
【发布时间】:2018-10-17 11:13:22
【问题描述】:

我创建了 2 个表单。 第一个是您要备份的按钮。 在第二个中有可以修改的路径。 如何参考按下“备份”按钮后将获得 2 个表单的路径。 关闭form2时保存路径 我知道如何以一种形式做到这一点,但不幸的是我不能参考另一种形式。

表格2的来源:

Private Sub Browser_from1_Click(sender As Object, e As EventArgs) Handles Browser_from1.Click
        Dim FolderBrowserDialog1 As New FolderBrowserDialog
        FolderBrowserDialog1.ShowDialog()
        TextBox1from.Text = FolderBrowserDialog1.SelectedPath

        If Browser_from1.Text <> "" And TextBox1from.Text <> "" Then
            Backup.StartCopy.Enabled = True

        End If

    End Sub

    Private Sub Browser_to1_Click(sender As Object, e As EventArgs) Handles Browser_to1.Click
        Dim FolderBrowserDialog1 As New FolderBrowserDialog
        FolderBrowserDialog1.ShowDialog()
        TextBox2to.Text = FolderBrowserDialog1.SelectedPath

        If Browser_to1.Text <> "" And TextBox2to.Text <> "" Then
            Backup.StartCopy.Enabled = True

        End If
    End Sub

    Private Sub TextBox1from_TextChanged(sender As Object, e As EventArgs) Handles TextBox1from.TextChanged

    End Sub

    Private Sub save_settings_Click(sender As Object, e As EventArgs) Handles save_settings.Click
        My.Settings.pathmem = TextBox2to.Text
        My.Settings.pathmem1 = TextBox1from.Text
        My.Settings.Save()
    End Sub

    Private Sub setting_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        TextBox1from.Text = My.Settings.pathmem1
        TextBox2to.Text = My.Settings.pathmem
    End Sub
End Class

【问题讨论】:

  • 那里没有与第二种形式相关的代码。表单是类,您可以向它们添加方法和属性,而不是让一个表单与另一个表单的内部结构混淆。请阅读How to Ask 并采取tour

标签: vb.net reference


【解决方案1】:

您不想创建对表单的引用 - 这将(或可能)创建一个全新的表单。您想保留表单参考。

这是通过传递对表单的引用来完成的,但是谈论一个表单摆弄另一个表单上的控件是一个坏主意,因为它破坏了封装。但是表单是类(它在每个类的顶部都这样说),因此您可以添加 PropertiesMethodsSub 和/或 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 更新数据库。

【讨论】:

    【解决方案2】:
    'SECOND FORM
    
    Public class secondForm (blah blah)
    Public overloads property owner as myMainForm
    'Must be only the form you prepared for that 
    
    Private sub secondForm_load(blah blah) handles blah blah
    Texbox1.text=Owner.customcontrol.text
    End sub
    
    End class
    
    'MAIN FORM
    
    public class myMainForm(blah blah)
    
    Private sub button1_click(blah blah) handles blah blah
    
    Dim NewSecondForm as secondForm = New secondForm
    NewSecondForm.owner(me)
    NewSecondForm.show(me)
    NewSecondForm.dispose()
    
    ' so you can have bidirectional communication between the two forms and access all the controls and properties from each other
    End sub
    End Class
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-07
      • 1970-01-01
      • 1970-01-01
      • 2013-10-15
      • 2017-06-01
      相关资源
      最近更新 更多