I am building a large data entry form and want to enable or disable groups of comboboxes based on a checkbox ( if the check box gets checked, the collection of combo boxes get enabled for user input and vice versa ). I want to use collection, because the comboboxes are not always going to be in sequential order ( example : Comboboxes 1-7, then Combobox 12, then 16, and 45-57 ). A collection seems ideal.
I've built the collections, added the comboboxes, and added items to the comboboxes. All the items are there in the comboboxes when I run the Application. I can enable or disable them individually, but I can't enable/disable the comboboxes as a collection.. how can I enable or disable them as a group ?
I can get this to work if I select all the combo boxes in my form, and then run the thru list matching the names against a variable ( as an example, for boxes 1 - 56 ), but that makes using a collection redundant. I am also going to want to output the data, in the collection groups, for later use.
I've been beating my head against the wall for a day or so on this..
Declare Collection
Dim CablesCollectionBoxes As New Collection
Add Comboboxes to collection
CablesCollectionBoxes.Add(ComboBox1)
CablesCollectionBoxes.Add(ComboBox2)
CablesCollectionBoxes.Add(ComboBox3)
.
<removed for space and readability>
.
CablesCollectionBoxes.Add(ComboBox56)
I am trying modify the collection of ComboBoxes to a disabled state, but the code below won't work.
for I as integer = 1 to 56
CablesCollectionBoxes.Item(i) = Disabled
next
It DOES work if I use this, but I'm not using the collection, I am running thru ALL the comboboxes and matching names :
For i As Integer = 1 To 56
Dim clsCombo As ComboBox = DirectCast(Me.Controls.Find("ComboBox" & i.ToString(), True)(0), ComboBox)
clsCombo.Enabled = True
Next
or this
ComboBox1.Enabled = True
ComboBox2.Enabled = True
ComboBox3.Enabled = True
ComboBox4.Enabled = True
.
<removed for space and readability>
.
ComboBox56.Enabled = True
How do I access the comboboxes as a group, and change the properties ? Did I declare the collection incorrectly ?
Don't use collection. Collections are soft-deprecated. Use List(Of T)
Dim comboList As New List(Of ComboBox)()
comboList.Add(cbo1)
comboList.Add(cbo2)
comboList.Add(cbo3)
' Imports System.Linq
comboList.ForEach(Sub(cbo) cbo.Enabled = True)
This is as close as you can get.
Now, if you want to have some selective way to enable/disable or whatever, you can use Tag property to mark and then it will look like this
comboList.Where(Function(cbo) cbo.Tag IsNot Nothing AndAlso CBool(cbo.Tag)).ToList().ForEach(Sub(cbo) cbo.Enabled = True)
Be sure that the check box and the enabled property of the combos are in syn when the program starts. Use the designer.
Private ComboCollection As New List(Of ComboBox)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
BuildCBCollection()
End Sub
Private Sub BuildCBCollection()
For Each ctrl As Control In Me.Controls
If TypeOf (ctrl) Is ComboBox Then
ComboCollection.Add(CType(ctrl, ComboBox))
End If
Next
End Sub
Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
For Each cb In ComboCollection
cb.Enabled = Not cb.Enabled
Next
End Sub
Related
In private sub form1_loader:
For each obj as object in Me.Controls
If TypeOf obj is windows.forms.textbox then
Directcast(obj, windows.forms.textbox).enabled = false
End if
Next
But I also wanted to have some certain textboxes to be enabled if any checkbox has been checked (even if there's only one checked)
And disable if none of the checkboxes are checked.
I am not familiar in coding and it's my first time for class activity so I don't know a lot.
Would there be a way for this one or should I manually code for every private sub of checkboxes?
This will enable three specific TextBoxes if and only if at least one of three specific CheckBoxes are checked:
Dim anyCheckBoxChecked = {CheckBox1, CheckBox2, CheckBox3}.Any(Function(cb) cb.Checked)
For Each tb In {TextBox1, TextBox2, TextBox3}
tb.Enabled = anyCheckBoxChecked
Next
You can extend that to any set of either type of control, e.g. all controls of that type in a specific container:
Dim anyCheckBoxChecked = Panel1.Controls.OfType(Of CheckBox)().Any(Function(cb) cb.Checked)
For Each tb In Panel2.Controls.OfType(Of TextBox3)()
tb.Enabled = anyCheckBoxChecked
Next
I have a CheckedListBox of 10 names A to J (it's a string but here I'm just using abc), and I want to make it so that every time a user check something, the text will be shown in the listbox simultaneously. I have tried this:
For i = 0 To chklistbxDrugAvailableList.Items.Count - 1
Dim drugs As String = CType(chklistbxDrugAvailableList.Items(i), String)
If chklistbxDrugAvailableList.GetItemChecked(i) Then
listbxYourOrder.Items.Add(drugs)
End If
'drugs = nothing
Next
But when I check A,B,C the text in the Listbox got repeated like so:
A
A
B
A
B
C
I don't know why this is happening. I didn't declare drugs as an array. Even when I used the drugs = nothing, it still give repeated values.
What should I do? Sorry if this is a noob question.
Here is how I would do the whole thing:
Private Sub CheckedListBox1_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
'Clear the current ListBox contents.
ListBox1.Items.Clear()
'Get the indexes of the currently checked items.
Dim checkedIndices = CheckedListBox1.CheckedIndices.Cast(Of Integer)()
'Add the current index to the list if the item is being checked, otherwise remove it.
checkedIndices = If(e.NewValue = CheckState.Checked,
checkedIndices.Append(e.Index),
checkedIndices.Except({e.Index}))
'Get the checked items in order and add them to the ListBox.
ListBox1.Items.AddRange(checkedIndices.OrderBy(Function(n) n).
Select(Function(i) CheckedListBox1.Items(i)).
ToArray())
End Sub
or like this:
Private Sub CheckedListBox1_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
'Get the indexes of the currently checked items.
Dim checkedIndices = CheckedListBox1.CheckedIndices.Cast(Of Integer)()
'Add the current index to the list if the item is being checked, otherwise remove it.
checkedIndices = If(e.NewValue = CheckState.Checked,
checkedIndices.Append(e.Index),
checkedIndices.Except({e.Index}))
'Get the checked items in order and add them to the ListBox.
ListBox1.DataSource = checkedIndices.OrderBy(Function(n) n).
Select(Function(i) CheckedListBox1.Items(i)).
ToArray()
End Sub
The difference is that, because the second option uses data-binding, the first item in the ListBox will be selected by default.
The reason that it needs to be a bit verbose is that the ItemCheck event is raised before the item is checked or unchecked. For that reason, we need to get the currently checked items first and then either add or remove the current item, depending on whether the current item is being checked or unchecked.
EDIT:
Here's an option that doesn't require clearing the ListBox:
Private Sub CheckedListBox1_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
Dim item = CheckedListBox1.Items(e.Index)
If e.NewValue = CheckState.Checked Then
ListBox1.Items.Add(item)
Else
ListBox1.Items.Remove(item)
End If
End Sub
The issue with that is that the items will appear in the ListBox in the order you checked them, rather than the order they appear in the CheckedListBox. The other options keep the items in the same order in both lists.
If I understand your question I would this:
lstbxYourOrder.Items.Clear()
For Each l As String In chklistbxDrugAvailableList.CheckedItems
listbxYourOrder.Items.Add(l)
Next
I am here to find out is it possible to complete my idea to save me time writing long code.
I have 1 main combobox with various items and some other comboboxed. Each combobox of them is called "Combo" + the item from the main combobox.
and I wonder can I, when I click on an item to hide the last used combobox and to show the combobox linked to this item?
1. hide last used combobox
2. show the combobox responding to the selected item from the main combox
Public Sub ComboBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox2.SelectedIndexChanged
Dim SelectedAction As String = "Combo" + ComboBox2.Text
lastcombobox.visible = false
' now to assign to the new combobox
lastcombobox = (SelectedAction as name of combobox) combobox
Lastcombobox.visible = true
End Sub
Strings are not controls. Strings are the data type of Control.Name; that is the Name property of the control object. You cannot cast a string to a control but all is not lost. Create your other Combo Boxes at design time and stack them on top of each other. Notice the Static keyword before lastComboBox. This persists the value between calls to the method. You could accomplish the same thing by making this variable a class level variable. The first time the method is called their will be nothing in lastComboBox therefore the check for IsNothhing. Control.Find returns an array so we must refer to ctl(0) - the first element of the array, since we know it will return only one.
Private Sub Combo2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles Combo2.SelectedIndexChanged
Dim SelectedAction As String = "Combo" & Combo2.Text
Static lastComboBox As ComboBox
If Not IsNothing(lastComboBox) Then
lastComboBox.Visible = False
End If
Dim ctl() As Control = Controls.Find(SelectedAction, True)
lastComboBox = CType(ctl(0), ComboBox)
lastComboBox.BringToFront()
lastComboBox.Visible = True
End Sub
I'm trying to set the length of a Combo Box control in the most efficient way possible. By length, I mean the number of items in the items collection of the Combo Box control.
This is the best attempt I have:
Dim cboNew As New ComboBox
For i As Integer = 0 To cboSelection.Items.Count - 1
cboNew.Items.Add(cboSelection.Items(i))
Next
cboSelection is another Combo Box control I have, I am pretty much trying to set the length of cboSelection to cboNew with one line of code (If cboSelection has 5 items, then set cboNew to have 5 items). I feel as if I have done this before, but have forgotten how.
If you are willing to use the DataSource property, you could do something like this:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ComboBox1.DataSource = New String() {"tony", "bruce", "clark"}
ComboBox2.DataSource = ComboBox1.DataSource
End Sub
I have a combo box that has a couple items in them, where they add text to a text box. I want to prevent the same item being selected twice in a row, because the index never changed, but it still runs the code.
Here's what I've done:
Dim intComboIndex As Integer = -1
Dim cboComboBox As ComboBox = CType(sender, ComboBox)
Dim intComboSelIndex As Integer = cboComboBox.SelectedIndex
If intComboSelIndex > -1 And intComboSelIndex <> intComboIndex Then intComboIndex = intComboSelIndex
Is there a more efficient way of doing this, without having to create a different combo box and compare the indexes?
You must store the previously selected index elsewhere, because at the moment you recreate the variable every time the event is raised.
I'd recommend storing the previously selected index at class level, and then compare that to the currently selected index.
Public Class Form1
Dim ComboBoxPrevIndex As Integer = -1 'Declared at class level, outside any Sub or Function.
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim SenderBox As ComboBox = DirectCast(sender, ComboBox) 'Get the control that raised the ever.
'Has the selection changed?
If ComboBoxPrevIndex <> SenderBox.SelectedIndex _
AndAlso SenderBox.SelectedIndex > -1 Then
'Do stuff...
End If
ComboBoxPrevIndex = SenderBox.SelectedIndex 'Set the new, previous index.
End Sub
End Class
You might have noticed that I used AndAlso instead of And. This is because of AndAlso is short-circuited, meaning that it will only check the condition on it's right if the condition on it's left evaluates to True.