adding multiple listbox items into one listbox - vb.net

I'm using vb.net form.
I have 8 listboxes (listbox1 , listbox2,listbox3..) each one contains many items and another empty listbox (listbox10). I'm trying to add first listboxes items into the listbox10
ex: ) listbox1 first items is 'A' , listbox2 first items is 'b' , listbox3 first items is 'c'...etc . Now listbox10 first item must be "Abc..."
The problem is i'm only able to add 3 listboxes into the listbox10
But i want to all 8 listboxes to include in the loop.
here is my code
Dim n As Integer = _
Math.Min(ListBox1.Items.Count, Math.Min(ListBox2.Items.Count, ListBox3.Items.Count))
For i As Integer = 0 To n - 1
ListBox10.Items.Add( _
ListBox1.Items(i).ToString + _
ListBox2.Items(i).ToString + _
ListBox3.Items(i).ToString)
Next

Create a List<Listbox> of all the listboxes that you want to work on.
Then, using Linq, is pretty easy to reach your objective
Dim controls = new List(Of Listbox)() From _
{ listbox1, listbox2, listbox3, ....etc.... }
Dim minCount = controls.Min(Function(x) x.Items.Count)
for x = 0 to minCount-1
listbox10.Items.Add(string.Join(" ", controls.Select(Function(lb) lb.Items(x).ToString)))
Next
Of course, if all the Listbox have the same amount of items then the calculation to find the listbox with the lower amount of items is useless, you could replace it using the Items.Count of any Listbox (However, in defensive programming, I would leave it)

Related

How to add multiple checkboxes in multiple columns (VBA)

I have a ListView with multiple columns. More precisely, the ListView contains 8 columns. 2 of them should be filled with checkboxes.
Currently only the first column contains checkboxes. It is defined as follows:
While Not rs.EOF
//first column with checkboxes
ListViewCustomer.ListItems.Add , , rs("Id")
ListViewCustomer.ListItems(ListViewCustomer.ListItems.Count).tag = rs("Status")
//second column etc.
ListViewCustomer.ListItems(ListViewCustomer.ListItems.Count).ListSubItems.Add , , rs("name")
....
//Here is the second column, which doesn't display the checkboxes
ListViewCustomer.ListItems(ListViewCustomer.ListItems.Count).ListSubItems.Add , , IIf(IsNull(rs("date_from")), "", rs("date_from"))
ListViewCustomer.ListItems(ListViewCustomer.ListItems.Count).tag = rs("Status2")
Wend
Do anyone have an idea how to add the checkboxes in the last column?
EDIT:
Is it possible to realize this column with adding via .Controls?
A ListView is a more expanded version of the ListBox control.
See ListBox control on msdn as well.
They both display records of rows (the ListView has more advanced formatting options). This however means that a record is a row. Therefore you select a row when you select one of the items.
The function of the checkbox is to allow the user to mark the row(s) that is the records(s) he selects.
Thus there is only one checkbox per row, at the front of the row.
Consider this code (this is Excel 2003 VBA, but gives you the idea):
Private Sub UserForm_Initialize()
Dim MyArray(6, 8)
'Array containing column values for ListBox.
ListBox1.ColumnCount = 8
ListBox1.MultiSelect = fmMultiSelectExtended
'Load integer values MyArray
For i = 0 To 5
MyArray(i, 0) = i
For j = 1 To 7
MyArray(i, j) = Rnd
Next j
Next i
'Load ListBox1
ListBox1.List() = MyArray
End Sub
You could do a custom ListBox or ListView if you really want. You could create a frame and put Labels and CheckBoxes on it. This is the only way to do this in Excel2003 where I tested. The ListBox object has no Controls child.
But this is more like a datagrid and not really a ListBox or ListView which by definition are a listing of records (rows).
Update:
I saw your update and that you really want to place the CheckBox at the end of the row.
If you only want one checkbox at the last row, you could do this custom checkbox. Again this is written for the ListBox, so need to convert it to your ListView if you want to.
Still requires a custom handling, but I had some time, so I did this code. See if you like it:
Private Sub ListBox1_Change()
For i = 0 To ListBox1.ListCount - 1
ListBox1.List(i, 3) = ChrW(&H2610)
Next i
ListBox1.List(ListBox1.ListIndex, 3) = ChrW(&H2611)
End Sub
Private Sub UserForm_Initialize()
Dim MyArray(5, 3)
'Array containing column values for ListBox.
ListBox1.ColumnCount = 4
ListBox1.MultiSelect = 0
ListBox1.ListStyle = 0
'Load integer values MyArray
For i = 0 To 5
MyArray(i, 0) = i
For j = 1 To 2
MyArray(i, j) = Rnd
Next j
MyArray(i, 3) = ChrW(&H2610)
Next i
'Load ListBox1
ListBox1.List() = MyArray
End Sub

Adding text between listboxes items

I'm using vb.net form.
I have 8 listboxes (listbox1 , listbox2,listbox3..) each one contains many items and another empty listbox (listbox10). I'm trying to add first listboxes items into the listbox10
ex: ) listbox1 first items is 'A' , listbox2 first items is 'b' , listbox3 first items is 'c'...etc . Now listbox10 first item must be "Abc..."
The problem is i want to add text ( string or number) between each listbox
ex:)listbox1 first items is 'A' , listbox2 first items is 'b' , listbox3 first items is 'c'...etc . Now I want listbox10 first item to be "The letters ABC is now done"
The main idea is to combine all listboxes items and adding text between them to create a meaningful sentence
here is my code
Dim controls = New List(Of ListBox)() From _
{ListBox1, ListBox2, ListBox3, ListBox4, ListBox5, ListBox6, ListBox7, ListBox8}
Dim minCount = Controls.Min(Function(x) x.Items.Count)
For x = 1 To minCount - 1
ListBox10.Items.Add(String.Join(" ", controls.Select
(Function(lb) lb.Items(x).ToString)))
Next
End Sub
Where i must to add my (string)?
Since you want to put different text between the listbox items, you would have to drop the String.Join function and loop through the ListBoxes yourself:
Dim sb As New StringBuilder
For i As Integer = 0 To controls.Count - 1
For j As Integer = 1 To minCount - 1
sb.Append(controls(i).Items(j).ToString)
Next
If i < controls.Count - 1 Then
sb.Append(" " & i.ToString & " ")
End If
Next
ListBox10.Items.Add(sb.ToString)

Clear and Add items to a DataGridViewComboBox but only for the selected row, not the entire column

There are couple of posts on DataGridViewComboBox but they don't cover this specific case.
I have a DGV in a shoe billing form, and the first three columns are comboboxes. The first, for Model; second, for Color; third, for Number.
Since I want people to only sell what's in stock, in CellValueChanged; depending on the ColumnIndex I clear the next combo and insert the corresponding Items. Quick example, I have "Nike Pegassus" in the first combo, I select "Green" on the second one, and I select all the available numbers for that model and color and insert those into third column, after I cleared items in there, in case there was another color selected. Here's part of the code
If e.RowIndex >= 0 Then
If e.ColumnIndex = 0 Then
Dim objColumna As DataGridViewComboBoxColumn = dtgDetalle.Columns(1)
Dim colItems As New Collection
Dim Dattabla As DataTable
Dim objColor As New clsColor(objObjeto.Sesion)
Dattabla = objColor.BuscarTodos("CodColor IN (select distinct Stock.CodColor from Stock inner join Color on Stock.CodColor = Color.CodColor where Stock.Cantidad > 0 AND Stock.CodModelo=" & CType(objColumna.Items(dtgDetalle.Rows(e.RowIndex).Cells(0).Value), clsElementoListaFactura).Codigo & ")")
objColor = Nothing
objColumna = dtgDetalle.Columns(1)
objColumna.Items.Clear()
dtgDetalle.Rows(e.RowIndex).Cells(1).Value = Nothing
dtgDetalle.Rows(e.RowIndex).Cells(2).Value = Nothing
For Each darRecord In Dattabla.Rows
objColor = New clsColor(objObjeto.Sesion)
objColor.Codigo = darRecord.item("CodColor").ToString
Dim objElemento As New clsElementoListaFactura(darRecord.item("Color").ToString, objColumna.Items.Count, "C", CInt(darRecord.item("CodColor").ToString), "1")
objColumna.Items.Add(objElemento)
objColor = Nothing
Next
objColumna.ValueMember = "ItemData"
objColumna.DisplayMember = "Name"
. . . . . .
That works just fine for only one row!
When I go to row #2 and change the index of the first combo, I want only to Combos (1, 1) and (1, 2) to be altered, but I get also (0, 1) and (0, 2) cleared and with the new values inserted.
What would be the best way for me to clear the items of a specific row within a column, and then insert items only in that cell?
If I'm not being clear, please ask. This is really starting to become a pain.
Thanks!

How can I control a ComboBox after another?

The code shows three ComboBox in a UserForm. Combobox2 pick four values ​​1, 2, 3, 4 from the sheet ("Data") and Combobox3 pick 6 values ​​(A, B, C, D, E, F) from the same sheet.
What should I do if I want to control Combobox3 after the value is chosen in Combobox2, such as If I choose 1 I want to just A, B, C should be in Combobox3, or if I choose 2 then only D, E found in Combobox3, etc.?
Thanks in advance for any suggestions!
Private Sub RapportFix_Initialize()
Dim ComboItems As Variant, i As Integer
Dim val As String
With RapportFix.ComboBox2 'Provtyp
.Clear ' remove existing entries from the listbox
ComboItems = Worksheets("Indata").Range("C5:C8").Value
ComboItems = Application.WorksheetFunction.Transpose(ComboItems)
' convert values to a vertical array
For i = 1 To UBound(ComboItems)
.AddItem ComboItems(i) ' populate the combobox
Next i
.ListIndex = -1 ' no items selected, set to 0 to select the first item
End With
With RapportFix.ComboBox3 'Kursplan
.Clear ' remove existing entries from the listbox
'Set sKursplanemoment = ComboBox3.Value
ComboItems = Worksheets("Indata").Range("M5:M10").Value
ComboItems = Application.WorksheetFunction.Transpose(ComboItems)
' convert values to a vertical array
For i = 1 To UBound(ComboItems)
.AddItem ComboItems(i) ' populate the combobox
Next i
.ListIndex = -1 ' no items selected, set to 0 to select the first item
End With
With RapportFix.ComboBox4 'Annat arbete
.Clear ' remove existing entries from the listbox
ComboItems = Worksheets("Indata").Range("E5:E8").Value
ComboItems = Application.WorksheetFunction.Transpose(ComboItems)
' convert values to a vertical array
For i = 1 To UBound(ComboItems)
.AddItem ComboItems(i) ' populate the combobox
Next i
.ListIndex = -1 ' no items selected, set to 0 to select the first item
End With
RapportFix.Show
End Sub
Each user form control has a number of events associated with it. The change event suggested by Cody is particularly easy to find as all you have to do is right-click the control in design view and choose "View Code", a sub outline will then be filled in.
As you can see above, there are two dropdown lists above the code page, one lists the controls and objects available and one lists the events. Choose a control and an event to get the outline sub for that event.
In this particular case, you need to use the change event of the controlling combo to first clear and then repopulate the dependent combo, just as you have done above. These are called cascading combos.
Private Sub ComboBox2_Change()
''Populate combo 3
End Sub
The only difference is you need to check that the list contains only those items that should appear for each value of the controlling combo. I would be inclined to do this with a list on a worksheet that I could easily control:
Item2 Item3
1 a
1 b
2 d
2 c
3 a
3 e
However, this does not seem possible for you, so you may wish to use Select Case
Private Sub ComboBox2_Change()
Select Case ComboBox2
Case "1", "2", "3"
''Add items x,y,z to combobox3
Case "a", "b", "c"
''Add items m,n,o to combobox3
Case Else
''Whatever
End Select
End Sub

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