none
Access form objects from other forms.

    Question

  • Greetings.

    Is there a relatively easy way to access objects on a different form within the same project in VB2015 ?  In an earlier version of VB, I could, for example, reference form1.label1.text or form1.textbox.text from form2 or other forms.  I could also reference public variables in other forms to get already computed data, etc.  I am having difficulty finding this in VB2015.

    Friday, April 7, 2017 7:22 PM

Answers

  • The following can be downloaded from here.

    Public Class Form1
        Private _Value As String
        Public ReadOnly Property Value As String
            Get
                Return _Value
            End Get
        End Property
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            _Value = "Karen"
            Dim f As New Form2
            f.Owner = Me
            Try
                f.Label1.Text = "Hello from parent"
                f.ShowDialog()
            Finally
                f.Dispose()
            End Try
        End Sub
    End Class
    

    Child

    Public Class Form2
        Private ownerForm As Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If Not String.IsNullOrWhiteSpace(TextBox1.Text) Then
                ownerForm.TextBox1.Text = TextBox1.Text
            Else
                ownerForm.TextBox1.Text = "Hello from child"
            End If
        End Sub
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            MessageBox.Show(ownerForm.Value)
        End Sub
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ownerForm = CType(Owner, Form1)
            TextBox1.Text = ownerForm.TextBox1.Text
        End Sub
    End Class


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Friday, April 7, 2017 8:37 PM
    Moderator
  • BB,

    Consider creating a NEW instance of the other form - rather than using the default instance.

    In the other form's code, for anything that you need access to, create public read-only properties and the rest is then obvious from there.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Friday, April 7, 2017 8:21 PM
  • Is there a relatively easy way to access objects on a different form within the same project in VB2015 ? 

    It depends on what the connection between the forms is.  Data that is required to populate controls on the new form when it is first shown is best passed in the constructor.  Other data to be accessed by the new form can be accessed from properties in the original form if a reference to the original form is provided to the new form, or properties of controls can be made available by passing a reference to the control.  Data that needs to be updated when it changes in the original form can be passed by messaging.  All these options are described here:
    https://vbdotnetblog.wordpress.com/forms/

    Whichever techniques you use, do not use the default form instance - it will certainly create problems later on. 

    Friday, April 7, 2017 9:31 PM
  • I am having difficulty finding this in VB2015.

    That's intentional. Those old VB6 habits made it difficult to apply good object oriented principles and were encouraging coding antipatterns.  If you compute some data in one place and need to use it in other places then that data should belong to its own object which can be passed around between the object which produces it and the object(s) which consume it.  If something happens on Form2 which should cause the value of the text on a Label on Form1 to change, then Form1 should likely be wired to listen for an event which Form2 raises and then respond to that event.  Even in the absence of strong application of the encapsulation principle, you should still be explicitly providing Form2 with an instance of Form1 in order to access the label, or passing Form2 a reference to the specific Label to manipulate.

    Karen has shown a simple example of passing a Form reference, and while you can do this, it should only be done in the most simple of scenarios.  As soon as you need to manipulate the other form in multiple ways, or need to pass the instance to multiple other forms, you immediately begin to build a spaghetti code situation where a given object is being manipulated in so many places and for so many reasons that it becomes very difficult to track down a bug when one occurs.

    If the text of, say, a status label needs to change frequently and by various means then there should likely be a single "StatusMonitor" class instance which becomes the sole source of changes to the label text.  Other Forms and objects can interact with the instance of StatusMonitor to alert the application to their actions and allow the StatusMonitor to worry about when and how to alert the user.  If you ever want to change the way alerts are displayed, you can do so in one place, regardless of how many other blocks of code may change the status.

    Every application needs to draw a line between what can be done and what should be done to solve any given problem, and the placement of that line varies based on the size, scale, and intended usage of the application.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Saturday, April 8, 2017 7:41 PM
    Moderator

All replies

  • Hi

    Yes, you can do that. Here is code for 2 Forms to illustrate

    FORM1

    ' Form1 with TextBox1 (text="Freddy wuz heer")
    Option Strict On
    Option Explicit On
    Option Infer Off
    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Form2.Show()
        End Sub
    End Class

    FORM2

    ' Form2 with TextBox1 (blank)
    Option Strict On
    Option Explicit On
    Option Infer Off
    Public Class Form2
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            TextBox1.Text = Form1.TextBox1.Text
        End Sub
    End Class


    Regards Les, Livingston, Scotland

    Friday, April 7, 2017 7:38 PM
  • BB,

    Consider creating a NEW instance of the other form - rather than using the default instance.

    In the other form's code, for anything that you need access to, create public read-only properties and the rest is then obvious from there.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Friday, April 7, 2017 8:21 PM
  • The following can be downloaded from here.

    Public Class Form1
        Private _Value As String
        Public ReadOnly Property Value As String
            Get
                Return _Value
            End Get
        End Property
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            _Value = "Karen"
            Dim f As New Form2
            f.Owner = Me
            Try
                f.Label1.Text = "Hello from parent"
                f.ShowDialog()
            Finally
                f.Dispose()
            End Try
        End Sub
    End Class
    

    Child

    Public Class Form2
        Private ownerForm As Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If Not String.IsNullOrWhiteSpace(TextBox1.Text) Then
                ownerForm.TextBox1.Text = TextBox1.Text
            Else
                ownerForm.TextBox1.Text = "Hello from child"
            End If
        End Sub
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            MessageBox.Show(ownerForm.Value)
        End Sub
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ownerForm = CType(Owner, Form1)
            TextBox1.Text = ownerForm.TextBox1.Text
        End Sub
    End Class


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Friday, April 7, 2017 8:37 PM
    Moderator
  • Is there a relatively easy way to access objects on a different form within the same project in VB2015 ? 

    It depends on what the connection between the forms is.  Data that is required to populate controls on the new form when it is first shown is best passed in the constructor.  Other data to be accessed by the new form can be accessed from properties in the original form if a reference to the original form is provided to the new form, or properties of controls can be made available by passing a reference to the control.  Data that needs to be updated when it changes in the original form can be passed by messaging.  All these options are described here:
    https://vbdotnetblog.wordpress.com/forms/

    Whichever techniques you use, do not use the default form instance - it will certainly create problems later on. 

    Friday, April 7, 2017 9:31 PM
  • I am having difficulty finding this in VB2015.

    That's intentional. Those old VB6 habits made it difficult to apply good object oriented principles and were encouraging coding antipatterns.  If you compute some data in one place and need to use it in other places then that data should belong to its own object which can be passed around between the object which produces it and the object(s) which consume it.  If something happens on Form2 which should cause the value of the text on a Label on Form1 to change, then Form1 should likely be wired to listen for an event which Form2 raises and then respond to that event.  Even in the absence of strong application of the encapsulation principle, you should still be explicitly providing Form2 with an instance of Form1 in order to access the label, or passing Form2 a reference to the specific Label to manipulate.

    Karen has shown a simple example of passing a Form reference, and while you can do this, it should only be done in the most simple of scenarios.  As soon as you need to manipulate the other form in multiple ways, or need to pass the instance to multiple other forms, you immediately begin to build a spaghetti code situation where a given object is being manipulated in so many places and for so many reasons that it becomes very difficult to track down a bug when one occurs.

    If the text of, say, a status label needs to change frequently and by various means then there should likely be a single "StatusMonitor" class instance which becomes the sole source of changes to the label text.  Other Forms and objects can interact with the instance of StatusMonitor to alert the application to their actions and allow the StatusMonitor to worry about when and how to alert the user.  If you ever want to change the way alerts are displayed, you can do so in one place, regardless of how many other blocks of code may change the status.

    Every application needs to draw a line between what can be done and what should be done to solve any given problem, and the placement of that line varies based on the size, scale, and intended usage of the application.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Saturday, April 8, 2017 7:41 PM
    Moderator
  • Hi BB2017,

    Please remember to close your thread by marking helpful post as answer, it is very beneficial to the other communities who face the same issue.

    Thanks for your understanding.

    Best regards,

    Cherry Bu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, April 20, 2017 7:03 AM
    Moderator