Looping through textboxes in groupbox give odd results - vb.net

I have the following code:
For Each control2 As Control In GroupBox3.Controls
If TypeOf control2 Is TextBox Then
Dim txt2 As TextBox = TryCast(control2, TextBox)
If counter > totalBoxes Then
totalBoxes += 1
txt2.Text = grade(totalBoxes)
End If
End If
Next
What I am doing is looping through each textbox in groupbox3. Then checking if the counter(total number of grades that are inputted in the form) are greater than the totalBoxes(which is set to 0) and finally I am putting the actual grade(A,B,C,D) into the textbox. The problem is that it is starting the loop at textbox 8(I have 10 textboxes) for some reason and going from there. Does anyone know what the problem is with my code?
Aaron

Well, the name of your textbox has no relation to its index in the .Controls collection of its parent.
One thing you could do is set the .tag property of each of your controls to the index you'd like to pass into your grade function.
textbox1.Tag = 1
textbox2.Tag = 2
...
That way you don't have to worry about which order the textboxes are in while iterating.

For Each box As TextBox In GroupBox3.Controls.OfType(Of TextBox).OrderBy(Function(t) t.Name)
If counter > totalBoxes Then
totalBoxes += 1
box.Text = grade(totalBoxes)
End If
Next box

Related

Excel VBA: Searching for value in listbox based on value set in textbox

I am trying to write a code for a search button which searches a listbox based a specific input set in a textbox.
The values searched are always numbers, and the listbox contains values from a single column.
The code i wrote can be found below but i don't understand why it is not functional.
Legend:
SearchButton: A Button which upon clicking is supposed to initiate the search
SearchBox: The textbox which will contain the search value
AvailableNumberList: The listbox which contains the data
Thanks for your help :)
Private Sub SearchButton_Click()
Dim SearchCriteria, i, n As Double
SearchCriteria = Me.SearchBox.Value
n = AvailableNumberList.ListCount
For i = 0 To n - 1
If SearchCriteria = i Then
AvailableNumberList.ListIndex = i
End If
Next i
End Sub
Is this what you are trying?
'If SearchCriteria = i Then
If AvailableNumberList.List(i) = SearchCriteria Then
Also use Exit For once a match is found :)
Additional to #Siddharth Rout solution, this code allows to search in the ListBox even if the TextBox does not have the full word/number:
Private Sub SearchButton_Click()
Dim SearchCriteria, i, n As Double
SearchCriteria = Me.SearchBox.Value
n = AvailableNumberList.ListCount
For i = 0 To n - 1
If Left(AvailableNumberList.List(i),Len(SearchCriteria))=SearchCriteria Then
AvailableNumberList.ListIndex = i
Exit For
End If
Next i
End Sub
Thanks everyone for their code! =D

Find all numericupdown in form visual basic

you can search on the form all the NumericUpDown and therefore report the value of all zero?
I would like to do something like a for loop that controls the form and see how many objects of that type are available, then if the user presses a key, all the NumericUpDown must return a value of 0 do not know if you can do this, I ask the 'help of you experts.
Dim count As Integer
count = 0
For i = 0 To Me.GroupBox1.Controls.Count - 1
Dim name As String
name = Me.GroupBox1.Controls(i).GetType().ToString()
If name.Contains("NumericUpDown") Then
count = count + 1
End If
Next
Label1.Text = count.ToString()
The form has a Controls collection. You can loop through that and check the type by calling GetType() [inherited from System.Object]. If you want to handle subtypes of NumericUpDown, you could try casting the control to NumericUpDown while catching the exception you will see if the control is not a NumericUpDown.
Your VB coding skills are probably better than mine. Been a long time since I wrote VB. Here's a rough example. I put this code in a button click event. You can pull the whole solution from my GitHub repository: https://github.com/kc1073/Samples
Dim count As Integer
count = 0
For i = 0 To Me.Controls.Count - 1
Dim name As String
name = Me.Controls(i).GetType().ToString()
If name.Contains("NumericUpDown") Then
count = count + 1
End If
Next
Label1.Text = count.ToString()
KC

RichTextBox Highlighting

Goal
Programmatically highlight part of a string contained in a RichTextBox based on what is selected in a DataGridView.
See screenshot for a more visual example
As you can see, when an Option type (EC - Electrical) is selected, its options are displayed in another DataGridView to the right. From there, the user can check the ones he wishes to have included in the Conveyor Function Summary (Photoeye in this case) and it gets highlighted.
Code Used
This method is executed every time the Option Type DataGridView has a selectionchanged event.
Private Sub SummaryOptionsHighlight()
Dim strToFind As String = ""
Dim textEnd As Integer = rtbSummary.TextLength
Dim index As Integer = 0
Dim lastIndex As Integer = 0
'Builds the string to find based on custom classes - works fine
For Each o As clsConveyorFunctionOptions In lst_Options
If o.Included Then
If strToFind.Length <> 0 Then strToFind += ", "
If o.Optn.IsMultipleQty And o.Qty > 0 Then
strToFind += o.Optn.Description & " (" & o.Qty & "x)"
Else
strToFind += o.Optn.Description
End If
End If
Next
'Retrieves the last index of the found string: ex. Photoeye (3x)
lastIndex = rtbSummary.Text.LastIndexOf(strToFind)
'Find and set the selection back color of the RichTextBox
While index < lastIndex
rtbSummary.Find(strToFind, index, textEnd, RichTextBoxFinds.None)
rtbSummary.SelectionBackColor = SystemColors.Highlight
index = rtbSummary.Text.IndexOf(strToFind, index) + 1
End While
End Sub
Problem
What's going on isn't a highlight but more of a backcolor being set to that selection. The reason I say this is because when I click in the RichTextBox to indicate that it has focus, it doesn't clear the highlighting. Perhaps there is an actual highlight instead of a backcolor selection?
See the difference:
Selection Back Color:
Highlighting:
to highlight, you just need to do this:
if richtextbox1.text.contians("photoeye") then
richtextbox1.select("photoeye")
end if
this should work for what you are trying to do

Multi Select List Box

I have a list box on a form and it works fine for what I want to do.
I am wanting to edit items on the form, this means populating the listbox and then selecting the relevant items.
My listbox contains a list of item sizes, i want to select the sizes which belong to the item being edited.
PLease can someone give me some pointers.
I tried me.lstItemSizes.SetSelected(i,true) but this only works for a single item.
Any help wil be much appreciated.
My Code:
Private Sub SelectItemSizes(ByVal itemID As Integer)
Dim itemSizes As IList(Of ItemSize) = _sizeLogic.GetItemSizes(itemID)
Me.lstItemSizes.SelectionMode = SelectionMode.MultiExtended
If (itemSizes.Count > 0) Then
For i As Integer = 0 To Me.lstItemSizes.Items.Count - 1
For x As Integer = 0 To itemSizes.Count - 1
If (CType(Me.lstItemSizes.Items(i), PosSize).SizeID = itemSizes(x).SizeID) Then
Me.lstItemSizes.SetSelected(i, True)
Else
Me.lstItemSizes.SetSelected(i, False)
End If
Next
Next
End If
End Sub
Did you set the selectionmode to multi?
You need to specify that in order to allow multiple selections.
Then you can do:
Dim i as Integer=0
For i=0 To Me.listBox.SelectedItems.Count -1
'display the listbox value
next i
Here is a screen shot:
After you set the property on the listbox then call setselected based on the values you want selected.
me.lstItemSizes.SetSelected(3,true)
me.lstItemSizes.SetSelected(4,true)
me.lstItemSizes.SetSelected(9,true)
Here you can add 20 numbers and only select the even.
Dim i As Integer
'load the list with 20 numbers
For i = 0 To 20
Me.ListBox1.Items.Add(i)
Next
'now use setselected
'assume only even are selected
For i = 0 To 20
If i Mod 2 = 0 Then
Me.ListBox1.SetSelected(i, True)
End If
Next
3rd edit
Look at the way you are looping, lets assume I create a list of integers, my vb.net is rusty I mainly develop in C#. But assume you did this:
Dim l As New List(Of Integer)
l.Add(2)
l.Add(6)
l.Add(20)
You only have three items in your list, so first loop based on the items on your list, then within the items in your listbox, you have it vice versa. Look at this:
Dim i As Integer
Dim l As New List(Of Integer)
l.Add(2)
l.Add(6)
l.Add(20)
'load the list with 20 numbers
For i = 0 To 20
Me.ListBox1.Items.Add(i)
Next
Dim lCount As Integer = 0
For lCount = 0 To l.Count - 1
For i = 0 To 20
If i = l.Item(lCount) Then
Me.ListBox1.SetSelected(i, True)
Exit For
End If
Next
Next
In the code my l is a list of just 3 items: 2, 6, and 20.
I add these items to l which is just a list object.
So now I have to loop using these 3 numbers and compare with my listbox. You have it the opposite you are looping on your listbox and then taking into account the list object.
Notice in my for loop that once the item in my list is found I no longer need to loop so I exit for. This ensures I dont overdue the amount of looping required. Once the item is found get out and go back to the count of your list object count.
After running my code here is the result
You have to change the ListBox.SelectionMode property in order to enable multiple-selection.
The possible values are given by the SelectionMode enum, as follows:
None: No items can be selected
One: Only one item can be selected
MultiSimple: Multiple items can be selected
MultiExtended: Multiple items can be selected, and the user can use the Shift, Ctrl, and arrow keys to make selections
So, you simply need to add the following line to the code you already have:
' Change the selection mode (you could also use MultiExtended here)
lstItemSizes.SelectionMode = SelectionMode.MultiSimple;
' Select any items of your choice
lstItemSizes.SetSelected(1, True)
lstItemSizes.SetSelected(3, True)
lstItemSizes.SetSelected(8, True)
Alternatively, you can set the SelectionMode property at design time, instead of doing it with code.
According to MSDN, SetSelected() can be used to select multiple items. Simply repeat the call for each item that needs to be selected. This is the example they use:
' Select three items from the ListBox.
listBox1.SetSelected(1, True)
listBox1.SetSelected(3, True)
listBox1.SetSelected(5, True)
For reference, this is the MSDN article.
Because my code had the following loops:
For i As Integer = 0 To Me.lstItemSizes.Items.Count - 1
For x As Integer = 0 To itemSizes.Count - 1
If (CType(Me.lstItemSizes.Items(i), PosSize).SizeID = itemSizes(x).SizeID) Then
Me.lstItemSizes.SetSelected(i, True)
Else
Me.lstItemSizes.SetSelected(i, False)
End If
Next
Next
The first loop loops through the available sizes and the second loop is used to compare the item sizes.
Having the following code:
Else
Me.lstItemSizes.SetSelected(i, False)
End If
Meant that even if item i became selected, it could also be deselected.
SOLUTION:
Remove Me.lstItemSizes.SetSelected(i, False) OR Include Exit For

VB.NET..... Loop help

I am using My.Settings in visual studio 2008 to store information, for when the user runs the program again.
I have that working fine... but as I am using 12 textboxes I don't want to write...
my.settings.grade1 = textbox1.text
for each one, and I am also making calculations using the stored information, so I dont want to be writing my.settings.grade1 + my.settings.grade2 etc..
Any help welcome
Thanks =)
On your form that has the textboxes, add them to a collection or an array of textboxes when the form is initialised.
Then, iterate through the collection or array of textboxes to assign to the setting value.
If you don't want to manually code the assignment of the textboxes into the array, then in your form initialisation code, iterate through all controls on the form and check for the control type or a specfici 'Tag' you assign to each textbox, then add each textbox to the array that way.
For Each c as Control in Me.Controls
If c.Tag.ToString() = "Grade" Then
' Add Items to collection here '
End If
Next c
Have you considered using ApplicationSettings Binding to automatically bind your values to your Textboxes.Text properties. This will support 2-way binding and then all you have to do is Call Save when you close.
or you could do something like this:
given the your textboxes are named along the lines of: Grade1, Grade2, Grade3, etc.
you could store the Grades in an Array and then loop through the array:
((TextBox)form.findControl("Grade" + i.ToString())).Text = Grade(i)
Depending on your calculation, then you could also execute the calculation inside the loop.
Populate a List of grade textboxes:
'at the class level'
Public GradeBoxes(11) As TextBox
Const grade As String = "GRADE"
'when the form is created'
Dim i As Integer = 0
For Each ctr As Control In Controls
If TypeOf (ctr) Is TextBox AndAlso ctr.Name.ToUpper.StartsWith(grade) Then
i = CInt(ctr.Name.SubString(grade.Length))
If i >= 0 AndAlso i < GradeBoxes.Length Then GradeBoxes(i) = ctrl
End If
Next ctr
For Each box As TextBox in GradeBoxes
If box IsNot Nothing AndAlso My.Settings(box.Name) IsNot Nothing Then
box.Text = My.Settings(box.Name)
End If
Next box
Save grades:
For Each box As TextBox in GradeBoxes
If box IsNot Nothing AndAlso My.Settings(box.Name) IsNot Nothing Then
My.Settings(box.Name) = box.Text
End If
Next box
My.Settings.Save()
Do you mean something like?
Dim sum As Long
Dim grades(11) As Long
Dim i As Integer = 0
For Each ctr In Controls
If TypeOf (ctr) Is TextBox Then
grades(i) = CLng(ctr.Text)
sum = sum + grades(i)
i = i + 1
End If
Next