How to pass a form, object or data to a second form

前端 未结 2 1874
执念已碎
执念已碎 2020-12-04 01:24

I have created 2 forms. The first one is the button that you want to back up. In the second there are paths that can be modified. How to make a reference that after pressing

相关标签:
2条回答
  • 2020-12-04 01:42

    You dont want to create a reference to a form - that would (or could) create a whole new form. You want to hold onto the form reference.

    This is done by passing a reference to the forms, but the talk of one form fiddling with the controls on another form is a bad idea because it breaks encapsulation. But forms are classes (it says so at the top of each one), so you can add Properties and Methods (Sub and/or Functions) to facilitate passing information back and forth.

    Method One - Passing a Form Reference

    The simplest way is to pass whatever the other form needs in the constructor:

    ' form 1 / "main" form / form to return to
    
    Dim frm As New Form6(Me)
    
    frm.Show()
    Me.Hide()
    

    In order for this to work, you need to modify the constructor (Sub New) on the destination form:

    Private frmReturnTo As Form
    Public Sub New(f As Form)
        ' This call is required by the designer.
        InitializeComponent()
    
        frmReturnTo = f
    
    End Sub
    

    It is best not to create your own constructor until you are familiar with them. Use the drop downs at the top of the code window: from the left pick the form name; from the right, select New. The designer adds required code to them which must not be changed.

    Do not add any code before the InitializeComponent() call at least until you are familiar with the life cycle of a form. The form and its controls do not exist until that runs.

    To return to the "main" form:

    If frmReturnTo IsNot Nothing Then
        frmReturnTo.Show()
    End If
    

    You may want to remove some of the title bar buttons or add code to the form Closing event to handle when the user closes via the system menu or buttons.

    Using the constructor is ideal for cases where there is some bit of data which the form must have in order to do its job.

    Method Two - Passing Data

    Thats all well and good, but what about passing data to another form? You can use the constructor for that too. In order to pass say, a string, integer and a 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
    

    Call it like this:

    ' method two: pass data you want to share in the ctor
    Dim frm As New frmData("hello", 6, New Point(150, 550))
    
    frm.Show()
    

    Result:

    Method Three: Properties

    Thats fine, but if there is a lots of data that way can get cumbersome. Plus, you may want to update some of the data from the calling/main form. For this you can create Properties on the form to handle the data:

    Public Property Label1Text As String
        Get
            Return Me.Label1.Text
        End Get
        Set(value As String)
            Me.Label1.Text = value
        End Set
    End Property
    

    Rather than a private variable to act as the backing field, one of the controls is used. The name leaves a bit to be desired as it exposes implementation details. So, use names which describe what the data represents rather than where it displays.

    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
    

    A point was used just to show that other data types can be used. Setting those values from the calling/original/source form:

    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
    

    The destination controls would well have been TextBoxes for the user to edit. The Property "wrappers" allow you to fetch those values back, so in this case, a Dialog was used.

    Method Four: Methods

    You can also use methods as a way to pass data to the second/helper form. Here a List(of T) collection will be passed. In the child/display form a method is added to receive the data which it then displays. The task represented is proofing or viewing a filtered list:

    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
    

    In the main/calling form:

    ' form level variable
    Private frmDV As frmDataView
    

    elsewhere...perhaps in a Click event:

    ' 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
    

    Result:

    With DataBased apps a modified version of this can allow for the case where you display DataGridView data in detail form on another form. You need not have the second form rung SQL to add or update the record, and then the main form running another query to "refresh" the display. If the DataSource is a DataTable backed up by a fully configured DataAdapter, pass the DataTable and have the child form add, change or delete using that. The data will automagically be in the DataTable and DataGridView`.


    There are other ways to do this, but they generally all boil down to passing something from A to B. Which way is "best" depends on what the app does, the use-case and the nature of the data. There is no one right way or best way.

    For instance, Properties and in many cases Functions allow the B Form to close the feedback loop. With DB items, a DataChanged property might tell the calling form that data was added or changed so that form knows to use the DataAdapter to update the db.

    0 讨论(0)
  • 2020-12-04 01:46
    '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
    
    0 讨论(0)
提交回复
热议问题