Kev
Kev

Reputation: 37

textbox on form within form not updating

I'm trying to understand more about VB.NET and Multiple forms so I can make my code better.

I have a SQL database table that holds the live data for all 14 processes, the monitor program updates a form showing the progress of all the processes. Years ago in MS Access I would have simply used a rolling subform to show the contents of the table.

However, my first attempt in VB.NET is to have "many" textboxes, basically 14 lines of textboxes and my code has 14 very similar parts updating all the textboxes. There has to be a better way :(

For Example:

txtProcessID1.Text TxtStatus1.Text ProgressBar1 ......

txtProcessID2.Text TxtStatus2.Text ProgressBar2 ......

txtProcessID3.Text TxtStatus3.Text ProgressBar3 ......

So, I'm trying to come up with a code where I create a SubForm that looks like one controller line, then create 14 instances of this subform on my mainform.

My test code seems to work but the textboxes on the subforms are not updating the contents on screen!! Even though when I call back the contents of .text it is what I expect.

Why does this example code not work, and is my solution the best way to complete this?

Public Class MainForm
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        SubForm.SetText = Me.TextBox1.Text    ' Try to change contents of a TextBox on the SubForm
        Me.TextBox2.Text = SubForm.SetText    ' Data comes back as expected, but the subform textbox remains unchanged.
    End Sub
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim objSubForm As New SubForm()
        objSubForm.TopLevel = False
        Me.Panel1.Controls.Add(objSubForm)
        objSubForm.Show()
    End Sub
End Class

Public Class SubForm
    Public Property SetText() As String
        Get
            SetText = TextBox1.Text
        End Get
        Set(ByVal Value As String)
            Me.TextBox1.Text = Value                  ' Control is not updated of the SubForm.
            Debug.Print("Value = " & Value)           ' The Value is Passed Correctly.
            Debug.Print("Text = " & TextBox1.Text)    ' And the property of the control has been updated.
        End Set
    End Property
End Class

Many Thanks

Kev

Upvotes: 0

Views: 1598

Answers (2)

Kev
Kev

Reputation: 37

Thanks Steve, I applied the new code in just half an hour based on your fix.

Here's a basic example of my code that gives me 14 subforms I can update.

I've moved away from creating a property in the subform in favour of directly updating the TextBox control.

The solution has given me "MUCH" less code and now I can add another detail to the one subform and show that for all processes.

Thanks Again! Kev

Public Class MainForm
Dim objSubForm(14) As SubForm
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    'Update the 14 forms
    For n = 0 To 13
        objSubForm(n).TextBox1.Text = Me.TextBox1.Text & " " & n
    Next
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    ' create 14 subforms
    For n = 0 To 13
        objSubForm(n) = New SubForm()
        objSubForm(n).TopLevel = False
        Me.Panel1.Controls.Add(objSubForm(n))
        objSubForm(n).Location = New Point(0, 20 * n)
        objSubForm(n).Show()
    Next
End Sub
Private Sub MainForm_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
    ' CLear up
    If objSubForm IsNot Nothing Then
        For n = 0 To 13
            objSubForm(n).Close()
        Next
    End If
    For n = 0 To 13
        objSubForm(n) = Nothing
    Next
End Sub
End Class

Upvotes: 0

Steve
Steve

Reputation: 216273

In your button click you are referencing the class name SubForm, this in VB.NET is called as the default automatic instance of a form, but this is not the same instance that you display in your Form_Load. Here you create a different instance called objSubForm and this is the instance that you display.

To fix you need to keep the objSubForm as a global instance and refer to this global when you click

Public Class MainForm
    Dim objSubForm As SubForm

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        objSubForm.SetText = Me.TextBox1.Text    ' Try to change contents of a TextBox on the SubForm
        Me.TextBox2.Text = objSubForm.SetText    ' Data comes back as expected, but the subform textbox remains unchanged.
    End Sub
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        objSubForm = New SubForm()
        objSubForm.TopLevel = False
        Me.Panel1.Controls.Add(objSubForm)
        objSubForm.Show()
    End Sub
End Class

Keep in mind that after this change you are responsible to effectively close and dispose the global instance.

Private Sub Form1_FormClosed(sender as Object, e as FormClosedEventArgs) _ 
     Handles Form1.FormClosed
   if objSubForm IsNot Nothing
      objSubForm.Close
   End If
   objSubForm = Nothing
End Sub

Upvotes: 1

Related Questions