2

I am still learing VB and have run into a problem with no decent tutorial. I have created a dynamic form that generates a Textbox and a Update button in each cycle of a loop.

I have declared the following global variables:

Dim tbRef As Textbox
WithEvents btnUpdate As Button

and later in the loop the following

Do Until counter = Maxrows 

counter = counter + 1
...
tbRef = New TextBox
...
Me.Controls.Add(tbRef)


btnUpdate = New button
...
AddHandler btnUpdate.Click, AddressOf btnUpdate_Click
Me.Controls.Add(btnUpdate)
...
tbRef.Text = ds.Tables("Records").Rows(counter - 1).Item(0)

Loop

And Finally

Private Sub btnUpdate_Click(sender As Object, e As EventArgs) Handles btnUpdate.Click
UpdateForm.tbRef.Text = Me.tbRef.Text
UpdateForm.Show()
End Sub

My Problem is:

The code generates the correct layout and the correct controls, and the button works fine if only one result is returned. If there is more than one button created, all the buttons refer to the contents of the last Textbox generated. The Only answer I got on the internet was that I must somehow use Ctype/DirectCast to cast the contents of each textbox to the button generated with it, but I cant find any tutorial on how to use these Operators in this context. Any help would be greatly appreciated.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • 2
    Your tbRef variable can keep track of only *one* textbox. But you create more than one. So that can't work, you need to declare it as a List(Of TextBox) instead. And in your Click event handler you need to know which specific button was clicked so you can find the correct textbox back in the list. You can do so with the button's Name or Tag property. All of this can get much easier if you create a UserControl instead. – Hans Passant Mar 27 '16 at 15:33

1 Answers1

2

As an option, you can use Tag property of button and store a reference to the text box in the tag property. Then when you want to find the textbox which the button is responsible for, you can unbox the text box from tag property of the button using DirectCast. The button itself is in sender parameter of the method which handles the event.

You also can assign a name to the text boxes and store the name in tag property and then find the control using that name.

For example

For index = 1 To 10
    Dim txt = New TextBox()
    'Set other properties
    'Add it to form

    Dim btn = New Button()
    btn.Tag = txt
    AddHandler btn.Click, New EventHandler(AddressOf btn_Click)
    'Set other properties
    'Add it to form
Next

The you can handle the event this way:

Private Sub btn_Click(sender As Object, e As EventArgs)
    Dim btn = DirectCast(sender, Button)
    Dim txt = DirectCast(btn.Tag, TextBox)
    MessageBox.Show(txt.Text)
End Sub
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Good answer. I was going to suggest this or the `Parent` property, but you were too fast. – Visual Vincent Mar 27 '16 at 15:34
  • @VisualVincent Thank you :) surely there are some other good options which may come into mind like the one which suggested by Hans, to create UserControl. – Reza Aghaei Mar 27 '16 at 15:39
  • By the way, all controls are located on a single form and have the same parent form. – Reza Aghaei Mar 27 '16 at 15:39
  • Oh, well his title says "In a dynamic form". Didn't read the question thoroughly. :) – Visual Vincent Mar 27 '16 at 15:43
  • @Vegito_ZA Let me know if you have any question about the answer :) – Reza Aghaei Mar 27 '16 at 16:51
  • Thank you so much, I bought "Learning Visual Basic .NET" but sadly it only covers the VERY basics. –  Mar 27 '16 at 17:28
  • You are welcome, don't worry, practice makes perfect. There are a lot of resources online which you can use to enhance your programming skill :) – Reza Aghaei Mar 27 '16 at 17:31
  • By the way, when you find a post that answers your question, you can click on check mark near the post to mark it as accepted answer. You can mark only one answer as accepted, but when you reached 15 reputations, you can also vote for as many post as you find helpful, including the accepted one, by click on up arrow near the post. – Reza Aghaei Mar 27 '16 at 17:33
  • A lot of my learning has been coding until I hit a snag and then look for a tutorial. Unfortunately, The problems only seem to become more complex and your site has been a great resource. I am Implementing your solution, although it means deleting my Sub Function for creating each control on the form and recoding everything into the For loop. Thank You Again –  Mar 27 '16 at 17:37
  • Oh and I almost forgot. Thanks for the `DirectCast` Tutorial :) –  Mar 27 '16 at 17:50
  • It seems you accidentally unaccepted the answer. You can click on check mark again to make it accepted. Or let me know if you find any thing wrong or unacceptable in answer :) – Reza Aghaei Mar 27 '16 at 17:58