Search combo box dropdown list based on user input - vb.net

I have a combo box with list items :
ABC
BAC
DEE
How can I have the list suggest based on input. e.g If user types A then it should show:
ABC
BAC
because they all contain the string character A.

Dim AList As List(Of String) = New List(Of String)
' Iterate through all the items in the combobox.
For Each item As Object In ComboBox1.Items
' If the current item contains A then add to the list.
If item.ToString.Contains("A") Then
AList.Add(item.ToString)
End If
Next
Or you can do it via LINQ, which is basically the same :
Dim AList As List(Of String) = New List(Of String)
Dim query = From item In ComboBox1.Items
Where item.ToString.Contains("A")
Select item
For Each item in query
AList.Add(item.ToString)
Next

Related

VB NET: how to find a list of string which has max item count, from several list of string

Could you please help me for this:
I have 5 lists of string, lets say A, B, C, D, and E:
A has 6 items
B has 5 items
C has 9 items
D has 2 items
E has 7 items
I need to sort or to find, "C" as the list which has max items.
I need to create tab in winform and on every tab I need to create datagridview programmatically. the maximum count in the list will be the maximum tab I need to create. And on every tab, there will be 1 item of every list member. Of course not all tab will have item from member which has small item count.
Previously what Ii did is iterate through table and datagrid to construct and solve the problem to avoid sorting the list cause I have no idea to find the max items on those lists.
UPDATE: Helped by Andrew
` Dim z As New List(Of List(Of String))
Dim a As New List(Of String)
a.Add("a1")
a.Add("a2")
a.Add("a3")
Dim b As New List(Of String)
b.Add("b1")
b.Add("b2")
b.Add("b3")
b.Add("b4")
b.Add("b5")
Dim c As New List(Of String)
c.Add("c1")
c.Add("c2")
c.Add("c3")
c.Add("c3")
z.Add(a)
z.Add(b)
z.Add(c)
Dim maxItems = z.Max(Function(p) p.Count)
MessageBox.Show(maxItems)`
If all you need is the length of the longest list...
Private A As New List(Of String) From {"Mathew", "Mark", "Luke", "John"}
Private B As New List(Of String) From {"Apples", "Oranges", "Pears"}
Private C As New List(Of String) From {"Haddock", "Salmon"}
Private D As New List(Of String) From {"Great Dane", "Poodle", "Bulldog", "Spaniel", "Golden Retriever"}
Private Sub GetMaxListLength()
Dim E() As Integer = {A.Count, B.Count, C.Count, D.Count}
Dim max = E.Max
MessageBox.Show(max.ToString)
End Sub
Both Mary answer and Andrew's work perfectly:
Dim z As New List(Of List(Of String))
Dim a As New List(Of String)
a.Add("a1")
a.Add("a2")
a.Add("a3")
Dim b As New List(Of String)
b.Add("b1")
b.Add("b2")
b.Add("b3")
b.Add("b4")
b.Add("b5")
Dim c As New List(Of String)
c.Add("c1")
c.Add("c2")
c.Add("c3")
c.Add("c3")
z.Add(a)
z.Add(b)
z.Add(c)
Dim eb() As Integer = {a.Count, b.Count, c.Count}
Dim max = eb.Max
Dim maxItems = z.Max(Function(p) p.Count)
MessageBox.Show(max)

VB.Net - How to search in a listbox bounded by dictionary?

So I have a listbox that is bounded by ID (key), and Name (Value). This is the method I used to bind the dictionary to the listbox:
listCustomer.DataSource = Nothing
listCustomer.Items.Clear()
Dim listCustomerSource As New Dictionary(Of String, String)()
While (dr.Read())
listCustomerSource.Add(dr.GetString(0), dr.GetString(1))
End While
listCustomer.DataSource = New BindingSource(listCustomerSource, Nothing)
listCustomer.DisplayMember = "Value"
listCustomer.ValueMember = "Key"
This is the method I have in textbox_textchange:
Private Sub searchList(ByVal textbox As TextBox, ByVal listbox As ListBox)
Dim hits = From item In listbox.Items.Cast(Of String)() Where (item.IndexOf(textbox.Text, StringComparison.OrdinalIgnoreCase) >= 0)
If hits.Any Then
listbox.SelectedItem = hits.First()
Else
listbox.ClearSelected()
End If
End Sub
I have tried it in a listbox with just a text (unbound) and it works just fine, but if I use it in a listbox with bounded dictionary, it gets an error 'Unable to cast object of type 'System.Collections.Generic.KeyValuePair`2[System.String,System.String]' to type 'System.String'.' upon typing in the textbox
This happens because when you bind a datasource the items are no more simple strings but instances of the datasource. When you bind a Dictionary every item in your ListBox is an instance of a KeyValuePair class. The values set on the DisplayMember or the ValueMember are used only for display purpose by the ListBox, your items are all KeyValuePair(Of String, String)
So, you just need to change you line that search your match to
Dim hits = From item In l.Items.Cast(Of KeyValuePair(Of String, String))()
Where (item.Value.IndexOf(x, StringComparison.OrdinalIgnoreCase) >= 0)

Combo Box items - Display Member for List(Of String)?

My project is in Visual Basic. I am trying to create a custom & savable "filter" for a DataGridView using several TextBoxes. Right now, any List(Of String) that is added to the Combo Box is displayed in the box as (Collection). I want my users to be able to select the one they created, so I would like the Lists to have a display name that can be selected in the Combo Box. Here is some of the code.
Dim savedFilter As New List(Of String)
savedFilter.Add(NameTextBox.Text)
savedFilter.Add(AgeTextBox.Text)
savedFilter.Add(NotesTextBox.Text)
ComboBoxSavedFilters.Items.Add(savedFilter)
Is it possible to add a display name for a List?
Or if you are lazy use buid-in generic class Tuple From MSDN.
Create collection of Tuple(Of String, List(Of String)) and use approach suggested by #Plutonix for binding collection to ComboBox
Dim savedFilter As New List(Of Tuple(Of String, List(Of String)))()
savedFilter.Add(
Tuple.Create("default",
New List From {"filter1", "filter2", "filter3"}))
savedFilter.Add(
Tuple.Create("Blue ones",
New List From {"filter4", "filter5"}))
savedFilter.Add(
Tuple.Create("Old ones",
New List From {NameTextBox.Text, AgeTextBox.Text, NotesTextBox.Text}))
With ComboBoxSavedFilters
.DisplayMember = "Item1" 'Name of first property in Tuple type
.ValueMember = "Item2" 'Name of second property in Tuple type -List
.DataSource = savedFilter
End With
Then SelectedValue will contain currently selected filter's collection,
which can be accessed like that
Dim filter As List(Of String) =
DirectCast(Me.ComboBoxSavedFilters.SelectedValue, List(Of String))
You could setup under My.Settings a StriingCollection
Initializing (you can omit the items added if so desired)
If My.Settings.Filters Is Nothing Then
My.Settings.Filters = New StringCollection() From {"One", "Two"}
End If
Setup items in a ComboBox
ComboBox1.Items.AddRange(My.Settings.Filters.Cast(Of String).ToArray)
Adding an item
My.Settings.Filters.Add(Now.ToShortDateString)
You can remove and clear items too.
Provide a Display Member for List(Of String)
Apparently, these are less a collection of filters than a collection of criteria or clauses for one Filter:
I condensed the code in the question, but there are 14 fields that can be filtered and there are multiple filters that can be applied on one field.
For the multiples per field, I am not sure I would want to store those individually, but keep the field criteria together. So, if you want to apply a name to these, a class would not only do that but could help manage the filter elements:
Public Class SuperFilter
Public Property Name As String
Public Property Elements As SortedList
Public ReadOnly Property FilterText As String
Get
Return GetFilterText()
End Get
End Property
Public Sub New(n As String)
Name = n
Elements = New SortedList
End Sub
Public Sub AddItem(filter As String)
Elements.Add(Elements.Count, filter)
End Sub
Public Sub InsetAt(index As Int32, filter As String)
Elements.Add(index, filter)
End Sub
Private Function GetFilterText() As String
Dim els(Elements.Count - 1) As String
Elements.Values.CopyTo(els, 0)
Return String.Join(" ", els)
End Function
Public Overrides Function ToString() As String
Return String.Format("{0} ({1})", Name, Elements.Count.ToString)
End Function
End Class
You would need to add methods and properties like Remove and Count but this should be enough to demonstrate. I am not sure about the SortedList, a Dictionary using the field name might be better, but something to control the order seems worthwhile. I am also unsure I would expose the Elements collection - managing it might be better left to the class.
Hopefully, the Combo displaying a set of these (as opposed to the filter elements/clauses) is the goal.
Private filters As New List(Of SuperFilter)
Add filter items to the list:
Dim item As New SuperFilter("Default")
item.AddItem("Id = 7")
filters.Add(item)
item = New SuperFilter("Blue Ones")
item.AddItem("Color = Blue")
filters.Add(item)
item = New SuperFilter("Complex")
item.AddItem("[Name] like %Bob% OR [Name] like %Alice%")
item.AddItem("AND Color = 'Blue'")
item.AddItem("AND Active=True")
item.AddItem("AND AccessRequired < 3")
item.AddItem("AND DateAdded > #2/11/2010#")
item.AddItem("AND CreatedBy = 'ziggy'")
filters.Add(item)
cbo1.DataSource = filters
cbo1.DisplayMember = "Name"
cbo1.ValueMember = "FilterText"
The value member could be the Elements - the collection of filter clauses, or it could be the query text. The GetFilterText method joins them together for you as part of what a filter manager class could/should:
For n As Int32 = 0 To filters.Count - 1
Console.WriteLine("Name: {0} Count: {1}{2}Text:{3}", filters(n).Name,
filters(n).Elements.Count,
Environment.NewLine, filters(n).FilterText)
Next
Result:
Name: Default Count: 1
Text:Id = 7
Name: Blue Ones Count: 1
Text:Color = Blue
Name: Complex Count: 6
Text:[Name] like %Bob% OR [Name] like %Alice% AND Color = 'Blue' AND Active=True AND AccessRequired < 3 AND DateAdded > #2/11/2010# AND CreatedBy = 'ziggy'
If you use "Elements" as the ValueMember you will get back the collection.
The combo displays the Name for the user. On the right, a label displays the ValueMember in this case, it is the FilterText or joined Elements. As I said, you could get back the actual collection as the SelectedValue instead, but that is available as part of SelectedItem.
If savable means beyond the life of the application instance, that is another question, but these are very easily serialized.

List of lists in vb.net

I am trying to create lists, that are then inserted into another list.
For some reason the latter list gets overwritten each time I try to add new list item to it.
For the code below, first I want to add items to Temp list and after certain conditions have been met, add the Temp list as an item to the Comp list. After that, the cycle repeats, new and different Temp list should be created and the added to the Comp list as next item. So each item in Comp list should be different.
But in the end I get a Comp list that is filled with Temp lists that are all identical to the last Temp list added.
What am I doing wrong?
Function UniqueValueList2(ByVal InputObject As List(Of Object)) As List(Of List(Of Object))
Dim vc As Integer = InputObject.Count
Dim i As Integer = 1
Dim Temp As New List(Of Object)
Dim Comp As New List(Of List(Of Object))
Dim CurrentObj As String
Dim PrevObj As String
Temp.Add(InputObject(0))
Do While i < vc
CurrentObj = InputObject(i).fieldName
PrevObj = InputObject(i-1).fieldName
If CurrentObj = PrevObj Then
Temp.Add(InputObject(i))
Else
Comp.Add(Temp)
Temp.Clear()
Temp.Add(InputObject(i))
End If
i = i + 1
Loop
Comp.Add(Temp)
UniqueValueList2 = Comp
End Function
Temp is holding the same reference. so making changes on it will change it.And you add and modify the same List
Comp.Add(Temp) 'the same Temp List
Temp.Clear() 'You will clear the same List
Temp.Add(InputObject(i))
So How you should do :
Comp.Add(Temp) 'we add old List
Temp=New List(Of Object) 'Temp now holds reference to new List
Temp.Add(InputObject(i))
This will work:
Comp.Add(Temp.ToList())
Temp.Clear()
Temp.Add(InputObject(i))

vb.net - multi-dimension array list

I've managed to make some single dimension array lists but I can't figure out a multi dimension arraylist.
Here's what I'm trying to do:
I have a database (mdb) with 5 columns that I want each row to be in an array list.
In PHP what I'd typically do is:
$array[$field1] = array($field2,$field3,$field4,$field5);
How I do the same in vb.net so anytime I need to fetch an item for a specific for the row1 I could call it?
For a single dimension I could do the following, but I can't figure out how to add more fields to a single array row:
Dim tmpArrayX As New ArrayList
tmpArrayX.Add(field(0))
tmpArrayX.Add(field(1))
etc...
If you want to use ArrayList, just make it's items contain other ArrayLists.
Or you could use normal arrays as:
Dim multiArray(2, 2) As String
multiArray(0, 0) = "item1InRow1"
multiArray(0, 1) = "item2InRow1"
multiArray(1, 0) = "item1InRow2"
multiArray(1, 1) = "item2InRow2"
Though my personal preference would be to use List as:
Dim multiList As New List(Of List(Of String))
multiList.Add(New List(Of String))
multiList.Add(New List(Of String))
multiList(0).Add("item1InRow1")
multiList(0).Add("item2InRow1")
multiList(1).Add("item1InRow2")
multiList(1).Add("item2InRow2")
Edit: How to find row:
Dim listIWant As List(Of String) = Nothing
For Each l As List(Of String) In multiList
If l.Contains("item1InRow2") Then
listIWant = l
Exit For
End If
Next
' This allows adding rows on the fly....Tested and it works!
Dim multiList As New List(Of List(Of String))
Dim ListRow As Integer = 0
For each record in some_source
dim Country as string = record.country 'from some source
dim Date as Date = record.Date 'from some source
dim Venue as string = record.Venue 'from some source
dim Attendance as string = record.Attendance 'from some source
multiList.Add(New List(Of String))
multiList(ListRow).Add(Country)
multiList(ListRow).Add(Date)
multiList(ListRow).Add(Venue)
multiList(ListRow).Add(Rating)
multiList(ListRow).Add(Attendance)
ListRow = ListRow + 1
next