Is there a way to update a TextBox when is not visible? - vb.net

I have a TextBox nested inside a TabControl.
Form->TabControl1->TabPage1->TabControl2->TabpPage2->GroupBox->TextBox
When the TabPage1, TabPage2 is selected, so the TextBox is visible to the user all the TextBoxEvents works OK, but when the user selects another TabPage it doesn't work.
I have a timer that send data periodically to know if an external device is present on a specific virtual COM port.
When the external device answer I put that data in that TextBox and set a global flag(boolean) to let the rest of the program that a device is present.
I'm processing the received data on a Private Sub and changing that TextBox with a Lambda expression like this
Me.Invoke(Sub()
Me.VersionFirmwareTxt.Text = RespX.Substring(5)
End Sub)

You can access the TextBox by name from anywhere whether it is visible or not, via casting (CType), and update its text value using the syntax:
'(from within the same Form, e.g., Form1)
CType(TabControl1.TabPages(1).Controls("VersionFirmwareTxt"), TextBox).Text = RespX.Substring(5)
'(from a different Form)
CType(Form1.TabControl1.TabPages(1).Controls("VersionFirmwareTxt"), TextBox).Text = RespX.Substring(5)
If you dynamically added the TextBox to the controls of the parent (TabPage), you will know exactly where the TextBox is located, since you would have already used, e.g.:
TabControl1.TabPages(1).Controls.Add(VersionFirmwareTxt)
Whereas if you manually added the TextBox to the TabPage, you also know the parent control.

Related

Do you have to show every tab before all textboxes actually populate?

I have a vb.net form that uses multiple textboxes across several different tabs. Within one of those tabs, I have a sub set of tabs. My save functionality calls stored procs for each tab and cycles through the values on each page to either do an update or a "add new". I noticed that while testing, some of the pages do not save or update any of the values in the textboxes. After a few days of investigating, I realized that if I edit something, then physically click through the other tabs, it all saves/updates properly. If I don't click through them, they don't all save. Is there a reason for this that I am missing? When you enter a search value, I cycle through the pages and populate them all at the same time so I was assuming it wrote those values BEFORE it physically rendered...I guess I am wrong?
From the TabPage documentation Remarks section
Controls contained in a TabPage are not created until the tab page is shown, and any data bindings in these controls are not activated until the tab page is shown.
So the answer to your question is "Yes the tabpage must be shown".
However, the definition of "shown" is subject to interpretation. In reality, all you need to do set the TabPage.Visible property to True and not actually cycle through and display each TabPage.
A recursive scan of the form for TabPage controls will work:
Private Shared Sub TabPagesVisible(parent As Control)
For Each c As Control In parent.Controls
If TypeOf c Is TabPage Then c.Visible = True
TabPagesVisible(c)
Next
End Sub
Example usage:
Sub SaveFormTabData()
TabPagesVisible(Me) ' Me refers to the containing form
' code to save control data
End Sub

Adding a letter to the name of an object

I have a series of pairs text fields that are pragmatically added, one is called 0_1 and the other is called 0_1w. I am wanting todo something to 0_1w when an event happens (keypress) to 0_1, and the same with 0_2, 0_3 etc...
Is it possible to just grab the sender for the keypress event and append the letter w to the end of it or is there any simple way I can do what I need with the w text field from within the other text field.
Thanks
Each control has a Name property, so if you cast the sender to Control, you'll be able to get that name string. You can then append "w" to it and look for another control with that name. You can look up controls by name using the Controls collection on the form.
Dim senderName As String = DirectCast(sender, Control).Name
Dim pairedName As String = senderName & "w"
Dim paired As Control = Me.Controls(pairedName)
However, the form's Controls collection only contains the controls that are directly added to it. If the sender is inside a container control, such as a Panel, only that panel control will be included in the form's Controls collection. In a case like that, you'd need to look at the panel's Controls collection. Therefore, since the two paired controls are probably inside the same container control, it would be safer to do this:
Dim paired As Control = DirectCast(sender, Control).Parent.Controls(pairedName)

Access Subform Source object

What I am trying to achieve is for a combo box (Combo_sf) selection to dictate the form in the subform control (sf_record) I have about 10 forms, their names are in the combo box data. I am new to VBA and am not sure if my approach is right:
Private Sub Combo_sf_AfterUpdate()
Dim strLoadTable As String
strLoadTable = "Form." & Me.Combo_sf.Value
MsgBox strLoadTable
Forms![frm_Mnu_Manage Configuration Settings]!sf_record.Form.SourceObject = strLoadTable
End Sub
I have placed this in the combobox's after update event but when I make my selection nothing happens in the form. Am I approaching this right or would another way work better?
Your approach should work. I put a combo box named cbxSubform on my main form and added one line of code to its AfterUpdate() event handler...
Private Sub cbxSubform_AfterUpdate()
Me.mySubform.SourceObject = Me.cbxSubform.Value
End Sub
...and changing the selection in the combo box switches the subforms immediately. Are you sure that the AfterUpdate() code for your combo box is actually firing? (You could add a MsgBox or a Debug.Print to check.)
It could be this line which is tripping you up:
strLoadTable = "Form." & Me.Combo_sf.Value
What is your form object called? If your form is called Form.myTableName it could be the . that is throwing it out, try setting it to a form without a dot in its name.
In this line, it seems the code attempts to change the SourceObject property of a Form object.
Forms![frm_Mnu_Manage Configuration Settings]!sf_record.Form.SourceObject = strLoadTable
However, SourceObject is a property of a subform control, not the form contained in that control. So if the subform control is named sf_record, do it this way.
Forms![frm_Mnu_Manage Configuration Settings]!sf_record.SourceObject = strLoadTable
Also, if the after update procedure runs from [frm_Mnu_Manage Configuration Settings], you can use Me to refer to the form.
Me!sf_record.SourceObject = strLoadTable
Finally, if Me.Combo_sf.Value is the name of a form, you don't need to prefix its name with "Form.". It worked either way in my test, but I would just leave off "Form.".
strLoadTable = Me.Combo_sf.Value

Make a button have multiple uses

okay... How do I explain this without being totally confusing?... Alright, I have this form that has MenuScripts (top-levels and second-levels). The problem that I am having is one of the second-levels is "Add" which brings you to another form when clicked. This other form has a button ("Record") and text boxes. This other form allows the user to input data and when the record button is clicked, the inputted data is written into a text file. Ok, so back to the first form. Another second-level MenuScript is "Update" which also brings the user to the other form; but first, the user has to click an item within a listbox to proceed. How do I get the data from the selected item to appear in the appropriate textboxes and how do I get the record button to update data instead of being confused and thinking it is only a add-data button?
Is there a way to use an "if" statement to say something like "if mnuAdd is clicked then" "elseif mnuUpdate is clicked then". Would something like that work for giving the record button multiple uses?
Also, if someone can give me some pointers on making sure the user selects an item within the listbox would definitely be a plus! Thanks, guys!
Unfortunately, I cannot add images since my reputation is too low.
Here is a visual representation of my ultimate goal
Easiest way: before displaying the second form set it's Tag property to something distinct – say "Add" or "Update" – depending on which menu item is selected. Then you just test the Tag value in the button's Click event and proceed accordingly.
As for determining whether a list item is selected: well if there isn't the ListBox's SelectedIndex property will be set to -1.
You need to put a public property on the second form (Details) which specifies which mode it is in. For instance, you could create a mode enumeration like this:
Public Enum EntryModes
AddBook
UpdateBook
End Enum
Then, define a public mode property on the second form, like this:
Public Property EntryMode As EntryModes
Get
Return _entryMode
End Get
Set(ByVal value As EntryMode)
_entryMode = value
End Set
End Property
Private _entryMode As EntryMode
Then, when you show the second form from the menu, just set the property first, before showing it:
Private Sub mnuAdd_Click(sender As Object, e As EventArgs)
Dim dialog As New DetailsDialog()
dialog.EntryMode = EntryModes.AddBook
dialog.ShowDialog()
End Sub
Private Sub mnuUpdate_Click(sender As Object, e As EventArgs)
Dim dialog As New DetailsDialog()
dialog.EntryMode = EntryModes.UpdateBook
dialog.BookToUpdate = ListBox1.SelectedItem
dialog.ShowDialog()
End Sub
As you can see, in the Upate menu click, I also added a line that passes the information for which book should be updated.

how to clear all tools in the vb.net from

i have used many of the controls in vb.net forms, including a textbox and combobox, but I want to clear all my text boxes at once, while not typing textbox1.clear() for each one.
Is there any other way to clear all my textboxes?
If I understand you question right, you should be able to loop through all the controls on your form and check to see what Control type they are. Based on their type, either set the textbox Text property to String.Empty, or your ComboBox to the index of a blank ListItem (presumably item zero).
Something like:
For Each ctrl As Control In Me.Controls
If TypeOf ctrl Is TextBox Then
CType(ctrl, TextBox).Text = String.Empty
Else
' do something similar for your ComboBox
End If
Next
You can parse through each control on your form and test what type of control that is and handle each type separately, but it is easier to simply set each control manually.
Consider writing a ClearForm routine that does all of this, that way all you have to do is call the method.