Using Visual Basic 6.0, I'm trying to populate one listbox with another listbox's items.
Can anyone please explain why the following sub fails to work properly,
getting a Type mismatch when passing two listboxes as parameters.
Public Sub copyListboxes(Byref lstFrom as Listbox, Byref lstTo as Listbox)
Dim i as integer
For i = 0 to lstFrom.Listcount -1
lstTo.Additem lstFrom.List(i)
Next i
End Sub
'Call copyListboxes(Listbox1,Listbox2) 'Type Mismatch ... ?
Thanks in advance.
I was able to reproduce your error by using Comboxes instead of Listboxes:
'1 form with:
' 1 command button: name=Command1
' 2 combobox controls: name=Listbox1 name=Listbox2
Option Explicit
Private Sub Command1_Click()
Call copyListboxes(Listbox1, Listbox2) 'Type Mismatch!
End Sub
Public Sub copyListboxes(ByRef lstFrom As ListBox, ByRef lstTo As ListBox)
Dim i As Integer
For i = 0 To lstFrom.ListCount - 1
lstTo.AddItem lstFrom.List(i)
Next i
End Sub
Private Sub Form_Load()
Dim intIndex As Integer
For intIndex = 1 To 10
Listbox1.AddItem CStr(intIndex)
Next intIndex
End Sub
To solve this you can either use Listbox controls or change your sub to work with Combobox controls:
Public Sub copyListboxes(ByRef lstFrom As ComboBox, ByRef lstTo As ComboBox)
Dim i As Integer
For i = 0 To lstFrom.ListCount - 1
lstTo.AddItem lstFrom.List(i)
Next i
End Sub
Related
I have several arrays named : Array1, Array2, Array3, ... and also some comboboxes named: cboArray1, cboArray2, cboArray3, ....
How can i write a GENERAL code to add elements of each array to corresponding combox. I know following code works, but its not GENERAL and ABSTRACT.
For i = 0 To Array1.Length - 1
cboArray1.Items.Add(Array1(i))
Next
For i = 0 To Array2.Length - 1
cboArray2.Items.Add(Array2(i))
Next
...
Working procedure maybe as follows: 1. Find all comboboxes in form (easy) 2. extract name of a combox (easy) 3. find similar-named array from code (difficult) 4. ....
I can use other sets like List, ... if it makes sense.
Here's what you're asking for using Reflection...though I'm not sure how useful this really is:
Public Class Form1
Private Array1 As String() = {"cat", "dog", "fish"}
Private Array2 As String() = {"alpha", "beta", "gamma"}
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
WireComboBoxes(Me)
End Sub
Private Sub WireComboBoxes(ByVal container As Control)
For Each ctl As Control In container.Controls
If TypeOf ctl Is ComboBox AndAlso ctl.Name.ToUpper.StartsWith("CBO") Then
Dim cb As ComboBox = DirectCast(ctl, ComboBox)
Dim arrName As String = cb.Name.Substring(3)
Dim fi As System.Reflection.FieldInfo = Me.GetType.GetField(arrName, Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.IgnoreCase)
If Not IsNothing(fi) Then
cb.DataSource = fi.GetValue(Me)
End If
ElseIf ctl.HasChildren Then
WireComboBoxes(ctl)
End If
Next
End Sub
End Class
I'm creating comboboxes on form load, but the thing is once I have added a new cb I can't access (set value, edit properties, etc) of the prior ones.
See Below Example:
Sub Start_stackoverflow()
Dim strings() As String = {"Green", "Purple", "Red"}
Dim x as integer
For x = LBound(strings) To UBound(strings)
NewDropDown(x,50,100,strings(x),strings(x))
Next x
End Sub
Private Sub NewDropDown(ByVal Number As Integer, ByVal PosX As Integer, ByVal PosY As Integer, ByVal Name As String, ByVal Text As String)
cbComboBox = New ComboBox
cbComboBox.Location = New Point(150, PosY - 4%)
cbComboBox.Name = Number
cbComboBox.ForeColor = Color.White
cbComboBox.BackColor = Color.DarkBlue
cbComboBox.Text = Name
cbComboBox.AutoSize = True
Me.Controls.Add(cbComboBox)
End Sub
So this is what happens, I can create the comboboxes just fine, add the values but if I wanted to edit the combobox Green for example (since it was first) I cant.
Even If I try this:
Sub Test()
UpdateComboBoxCurrentlySelected(Green, MyValueIwantSelected)
End Sub
Sub UpdateComboBoxCurrentlySelected(ByVal SetGrpName As ComboBox, ByVal CurrentItem As String)
SetGrpName.Text = (CurrentItem)
SetGrpName.SelectedText = (CurrentItem)
SetGrpName.SelectedItem = (CurrentItem)
SetGrpName.SelectedIndex = (CurrentItem)
SetGrpName.SelectedValue = (CurrentItem)
End Sub
Can anyone shed some light on this, that way I will know how to do it properly.
Thanks
You either need to hold a reference to the object you want to edit:
' At form level
Private dropdowns As Dictionary(Of String, Combobox) = New Dictionary(Of String, ComboBox)
' Populate from Sub Start_stackoverflow()
Dim dropdown As ComboBox = Nothing
' ...
dropdown = NewDropDown(x,50,100,strings(x),strings(x))
dropdowns.Add(dropdown.Name, dropdown)
' change UpdateComboBoxCurrentlySelected signature to
Sub UpdateComboBoxCurrentlySelected(ByVal SetGrpName As String, ByVal CurrentItem As String)
' get the dropdown by name
Dim dropdown as ComboBox = dropdowns(SetGrpName)
' ...
Or you can iterate over all the controls in the form looking for the one with the name you asked for.
Dim foundControl As ComboBox = Nothing
For Each control As Control In Me.Controls
If control.GetType Is GetType(ComboBox) AndAlso (control.Name = SetGrpName) Then
foundControl = control
End If
Next
If Not Nothing Is foundControl Then
' Do something with your control.
End If
I used to program in VB6 and am trying to write the same program in VB 2013. In this program I use an array of 49 buttons that all do the same thing when you click on them. I have figured out have to do the click function to a point:
Private Sub Button_Click(sender As Object, e As EventArgs) Handles Button9.Click, Button10.Click, Button11.Click, Button12.Click, Button13.Click, Button16.Click, Button17.Click, Button18.Click, Button19.Click, Button20.Click
...
End Sub
What I am trying to do is simplify the code down to using an array so I can just pass on the index. One other person asked the same question in 2010 and the best answer was:
Button[] array = { firstButton, secondButton };
That would work but I want something with less typing. I also tried the following with failure:
One
Button[] buttons = this.Controls.OfType<Button>().ToArray();
Two
For i = 1 To 100
Dim btns() As Button = Controls.Find("Button" & i, True)
Dim btn As Button
If btns IsNot Nothing Then
btn = btns(0)
'If buttons Is Nothing Then
' ReDim buttons(0)
'Else
' ReDim Preserve buttons(buttons.Length)
'End If
'buttons(UBound(buttons)) = btn
btn.Text = i - 1 'here you can change whatever you want
End If
Next
Three
Dim buttons() As Button
buttons = Nothing
For Each b As Button In Me.Controls
If buttons Is Nothing Then
ReDim buttons(0)
Else
ReDim Preserve buttons(buttons.Length)
End If
buttons(UBound(buttons)) = b
Next
I just can't get it to accept the existing buttons into an array. I hope someone can help.
If your Buttons are nested inside container controls (e.g. a GroupBox) then you will need to perform a recursive search for all buttons. Maybe something like this (totally unoptimized)...
Private Function FindAllButtons(root As Control) As List(Of Button)
Dim result As List(Of Button) = New List(Of Button)()
For Each c As Control In root.Controls
If TypeOf c Is Button Then
result.Add(DirectCast(c, Button))
ElseIf c.HasChildren Then
result.AddRange(FindAllButtons(c))
End If
Next
Return result
End Function
Then just call that in your Form:
Dim allButtons as List(Of Button) = FindAllButtons(Me)
' Add common Click handler
For Each b As Button In allButtons
AddHandler b.Click, AddressOf Button_Click
Next
Update Just for fun, here's a generic version to find other types of control.
Private Function FindAllControls(Of T As Control)(root As Control) As List(Of T)
Dim result As List(Of T) = New List(Of T)()
For Each c As Control In root.Controls
If TypeOf c Is T Then
result.Add(DirectCast(c, T))
ElseIf c.HasChildren Then
result.AddRange(FindAllControls(Of T)(c))
End If
Next
Return result
End Function
You can use that like:
Dim allButtons As List(Of Button) = FindAllControls(Of Button)(Me)
Dim allTextBoxes As List(Of TextBox) = FindAllControls(Of TextBox)(Me)
Option two will work, you just need to add the button found into a list. I suggest you add your buttons into a List(Of ) instead of an array. You can always convert the list into an array if you really need to.
Dim buttonList As New List(Of Button)
For i As Integer = 1 To 100
Dim btns() As Control = Controls.Find("Button" & i, True)
If btns IsNot Nothing AndAlso btns.Length > 0 Then
buttonList.Add(CType(btns(0), Button))
End If
Next
I am trying to get the value of a textbox and save it to a string array by clicking a button. I am getting a syntax error on the name(0) = TextBox1.Text line. I will be making it a dynamic array once I figure out how to do it (that's why I have a num variable as well because the button can be clicked multiple times).
Am I doing something wrong here?
Private Sub CommandButton1_Click()
Dim name(10) As String
Dim num As Integer
' Debug.Print TextBox1.Text
name(0) = TextBox1.Text
End Sub
'Name' is a built in name for excel.
Try:
Private Sub CommandButton1_Click()
Dim testArray(1 to 11) As String
Dim num As Integer
' Debug.Print TextBox1.Text
testArray(1) = TextBox1.Text
End Sub
EDIT: Changed the name of the array.
Does anyone know how to dynamically add an array to a bunch of comboboxes in VB.net? I could really use the help (I've been struggling with this all day). When I try to do it my way I get an error on form load.
My code:
Private Sub Form1_Load(ByVal sender as Object, ByVal e as EventArgs) Handles Me.Load
Dim MyArray() as String = {"a","b","c"}
For each ctl as ComboBox in Me.Controls
if ctl.tag = "yadda" then ctl.Items.AddRange(MyArray)
Next
End Sub
Error: "Unable to cast object of type '...Button' to type '...Combobox'."
I've tried so many variations to this code but I just can't get it to work. I will eventually have nearly a hundred similarly constructed comboboxes in my application, and I'd like to be able to programmatically initialize their items. Could someone please help?
Thanks,
Elias
This is the way to do it :
Public Class Form1
Function getControl(ByVal controlName As String) As Control
Dim numCtrls = Me.Controls.Count()
For I As Integer = 0 To numCtrls - 1
If Me.Controls.Item(I).Name = controlName Then
If TypeOf Me.Controls.Item(I) Is ComboBox Then
Return CType(Me.Controls(controlName), ComboBox)
End If
End If
Next
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim myArray As Array = {"a", "b", "c"}
Dim myComboBox As ComboBox
For Each ctl As Control In Me.Controls
If TypeOf ctl Is ComboBox Then
If ctl.Tag = "yadda" Then
myComboBox = getControl(ctl.Name)
myComboBox.Items.AddRange(myArray)
End If
End If
Next
End Sub
End Class
You loop through all controls (buttons, combo, etc ...) then you check if it is the type you want (ComboBox) and do whatever you need.
Good luck !