Textbox update from other form

jdy0803

Well-known member
Joined
Sep 9, 2012
Messages
73
Location
Santa Clarita
Programming Experience
10+
Here is 3 forms, form3, form1, form2.
form1 has textbox.
A. Start form3, form3 load form1, form1 load form2 and form2 try updating form1.textbox but failed.
B. But start form1, form1 load form2 and form2 try updating form1.textbox and then textbox is normally updated.


I don't know why B succeed but A fail.
How do I do to succeed in A?
(I attached project to show this.)
 

Attachments

Last edited by a moderator:
Your biggest issue with this is default instances. In Form1 and Form3 you're creating an instance of a form and showing it (a good thing) but then in Form2 when you set the textbox's text property on Form1 you're not getting the instance of Form1 from Form2's owner, which would be set if you passed it the Form1 reference when you call ShowDialog. What this means is in Form2 when you set Form1's textbox's text property, you're setting it for a copy of Form1 that isn't shown, so it looks like nothing happened.

I know the above may sound confusing, so here's what I mean using code:
Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Using frm As New Form2
            frm.ShowDialog(Me)
        End Using
    End Sub

End Class
And Form2:
Public Class Form2

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Me.Close()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim frm1 As Form1 = CType(Me.Owner, Form1)
        frm1.TextBox1.Text = "AAAA"
    End Sub

End Class
 
Form2 should not be touching a TextBox on Form1 in the first place. Form2 shouldn;t even have to know that Form1 exists. The proper way to do this is for Form2 to simply expose the data and then for Form1 to update its own TextBox. In Form2:
Public ReadOnly Property TextBoxText() As String
    Get
        Return "AAAA"
    End Get
End Property
In Form1:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Using frm As New Form2
        frm.ShowDialog()
        TextBox1.Text = frm.TextBoxText
    End Using
End Sub
 
What JMC is explaining is that while the code I provided does work, it's not recommended to allow the controls (your TextBox in this example) to be exposed outside of the form itself. By default when you place a control on a form it's declared as Friend which means it's directly accessible outside of the form when you should have it set to Private (you can change the control's Modifiers property to Private). When you need to allow the TextBox's Text property to be changed you should either, create a property on Form1 so you can do some validation in the Set before changing the Text property directly, or as JMC has suggested you should provide a property on Form2 that will provide the contents that will go into the TextBox and Form1 actually gets it from From2 (make a property for it, as JMC has shown).
 
It's not necessarily a big deal in small applications that aren't really going to go anywhere, such as you build when you're a beginner. When you start building commercial applications that may be around for a while though, you want to avoid tight coupling between types such as the code you're using creates. Your code means that Form1 will only work with Form2 and Form2 will only work with Form1, which means that the two are tightly coupled, i.e. they each depend absolutely on the other. By doing things the way I suggested, Form2 is decoupled from Form1, i.e. Form2 has no specific reliance on Form1.

Advantages of that include the fact that you can then use Form2 in more than one place in your application to provide the same or similar functionality. In your code, Form2 can only be used to update a specific TextBox in Form1. With my code, Form2 could be used to update any control in any form, or maybe some other data that is not even related to a control. You gain much greater flexibility with basically no extra effort. Even if you don't think you need that flexibility now, you may do at some time in the future and, if you allow for it now, you don't have to then make changes to both Form1 and Form2 in the future to get. Also, if you decide that you want to change how Form1 works in the future, a tightly coupled Form2 means the likelihood of having to change Form2 also is high. A decoupled Form2 means that it is unlikely to have to change because of a change to Form1.

Generally speaking, knowledge of hierarchy should flow one way only. In this case, Form1 has to have knowledge of Form2 because it needs to create an instance and display it, but there's no need for Form2 to know anything about Form1. There are times that two-way awareness is required but, even in those cases, the awareness in the upstream direction should be generalised. For instance, a control has a Parent property that contains a reference to its parent control. That means that the parent is aware of its children and children are aware of their parent. All the children know is that their parent is a control though, which makes sense because controls are designed to exist within other controls. They are not coupled to any one particular type of control though, so it is very loose coupling. Basically, the child in any hierarchical relationship should have no awareness of its parent, e.g. array elements have no awareness of the array, unless they specifically need to and then the coupling should still be as loose as possible while still providing the required functionality.
 
Back
Top