Check if combobox contains value of list vb.net - vb.net

I have list with duplicates values
Dim lstPlayerValidate As New List(Of Integer)
Dim duplicates = lstPlayerValidate.Where(Function(x) lstPlayerValidate.Where(Function(y) x = y).Count() > 1).Distinct().ToList
Now I want check if comboxes contains any value from this list.
I do it so:
If cmbPlayer.Items.Contains(duplicates) Then 'do something
My combobox has Item as List(Of Player), where PlayerID is value which I want compare. Perhaps I'm doing an unnecessary job creating another list with only id values. But I don't now how I can do it

Related

Why does ".Remove" affect all the items in a 2D structure assigned with a list?

I'm currently trying to create a Sudoku Solver, and on the step of assigning some possible values to a box that is not already preoccupied. (Bit of background info for why I'm doing this shebang: Sudoku is a number game based on a 9x9 grid, its contextual rules allow certain boxes in the grid that are not preoccupied to hold possible values during the process of solving )
To do this I created a structure, defined it as two dimensional, and populated it with a predefined list of integers using a for-loop.
Now when I tried to remove one integer from the list of a particular item in the two dimensional structure, I found out that all the lists of the items in the structure have had that integer removed. There's probably a simple solution to this, but I've been really struggling to find it. Hope the code below clarifies the somewhat confusing verbal explanation.
Structure Element
Dim PossibleValues As List(Of Integer)
Dim ElementValue As Integer
End Structure
Sub Main()
Dim List as New List(Of Integer)({1,2,3})
Dim TDP(8,8) as Element
For x as integer = 0 to 8
For y as integer = 0 to 8
TDP(x,y).PossibleValues = List
Next
Next
TDP(0,0).PossibleValues.Remove(1)
End Sub
Now I expect only TDP(0,0) would have a list of "2,3" when print out its list of integers, but when I check other items , i.e. TDP(1,0), its list is of integer is also "2,3"
Look at the assignment here:
TDP(x,y).PossibleValues = List
List(Of T) is a reference type, so this assigns a reference to the same List object to each of the array elements.
If you want each item to have it's own list of possible items, you need to either deep copy the list or create a new list:
Sub Main()
Dim TDP(8,8) as Element
For x as integer = 0 to 8
For y as integer = 0 to 8
TDP(x,y).PossibleValues = New List(Of Integer)({1,2,3})
Next
Next
TDP(0,0).PossibleValues.Remove(1)
End Sub

How to iterate display values in a combobox

I have a combobox whose values (displayvalue) are formatted (from a database query):
John Doe (11111)
where 11111 is the userID. The UserID is the login name for their machine and I want to default the selected value to the login UserID.
Since combobox.findstring(UserID) only matches if the entry begins with that string, I need to iterate through the values to look for the substring of UserID in the entries.
I've searched around here, but solutions seems to land all around this specific example. I can't seem to find a method that returns the display value at a specific index. What am I missing?
EDIT:
This is how I am populating my combobox:
Private Sub PopulateDropdown(strSQl As String, objControl As ComboBox, strTextField As String, strDataField As String)
Dim objdatareader As New DataTable
objdatareader = DataAccess.GetDataTable(strSQl)
objControl.DataSource = objdatareader
objControl.DisplayMember = strTextField
objControl.ValueMember = strDataField
End Sub
This may actually help folks trying to find the ValueMember of a combobox as well.
I am populating my combobox from a datatable, so this solution may only be valid from that. I am not really sure why this works. I just stumbled upon it.
First, I started by doing a for each item in combobox.items. According to intelisense, there is no property of .value, .text, .DisplayMember, or anything related to that. I did notice that the return type on combobox.items is a DataRowView. I am not sure why that is, but I went with it. One of the members of DataRowView is Row. It turns out, each column from the DataTable is added to the Row collection in 'item's' DataRowView. Rows(0) is the first column, Row(1) is the second, etc. I was then able to look in the Row's full text to find my userid, and then select that row by using the FindExactString of the combobox. The below code works (I built the datatable manually in this example):
dim UserID As String="12345"
dim MyTable as New Datatable
MyTable.Columns.Add("Value", Type.GetType("System.String"))
MyTable.Columns.Add("Text", Type.GetType("System.String"))
MyTable.rows.add("1","Bob Smith(11223)"
MyTable.rows.add("2","George Brown(12345)"
cboAssignedID.datasource=MyTable
cboAssignedID.DisplayMember="Text"
cboAssignedID.ValueMember="Value"
For Each item In cboAssignedID.Items
If InStr(item.Row(1).ToString, UserID) > 0 Then
cboAssignedID.SelectedIndex = cboAssignedID.FindStringExact(item.Row(1).ToString)
End If
Next

Create a dictionary out of a list vb.net

i have a list with 2 columns (clm1=StoreID and clmn2=ProductID).
i need to loop through this list and create a dictionary(StoreID , List(of ProductID))
i am using vb.net . can you please help me with the loop i have to make?
The list data is something like
StoreID ProductID
1 234
2 456
1 222
3 768
1 100
9 876
e.t.c.
I assume that your data is stored somewhat like this:
Structure Item
Public StoreID As Integer
Public ProductID As Integer
End Structure
Dim l As List(Of Item)
Then you have two options. The first one is to create the dictionary by hand:
Dim dictionary As New Dictionary(Of Integer, List(Of Integer))
For Each item As Item In l
Dim subList As List(Of Integer)
Dim keyExists = dictionary.TryGetValue(item.StoreID, subList)
If keyExists Then
subList.Add(item.ProductID)
Else
subList = New List(Of Integer)
subList.Add(item.ProductID)
dictionary.Add(item.StoreID, subList)
End If
Next
Here, you just iterate all items. Check the dictionary if it already contains an entry for the store id. If so, just add the product id. If not, create an entry and then add the product id.
If you're not overly concerned with performance, you can use the following LINQ expression to create the dictionary:
Dim dictionary = l.GroupBy(Function(item) item.StoreID) _
.ToDictionary(Function(group) group.Key, _
Function(group) group.Select(Function(item) item.ProductID) _
.ToList())
You first group the elements by their StoreID. Then, the ToDictionary() method creates the dictionary. It takes two parameters. The first one is a function that specifies the key of each element. In this case, we want to use the group's key as the dictionary key (which is the store id). The second parameter is the value that is inserted in the dictionary. First, we use Select to map each Item to its ProductID (because we want to store product ids and not entire items. Then we call ToList() to generate a list from the items in the group.

Using a LINQ query to populate a combo box with data from an access database

In VB.Net:
I am trying to populate a combo box on my form using data from a MS Access database. Specifically; taking all of the last names from the database, sorting them in ascending order in an output list which I named players and then adding each item in players to my combo box (cboPlayer).
Public Sub GetPlayers()
Dim PlayerLastName As New List(Of String)
PlayerLastName.Add("Smith")
PlayerLastName.Add("Hill")
PlayerLastName.Add("Beyer")
PlayerLastName.Add("Wilson")
PlayerLastName.Add("Hudson")
PlayerLastName.Add("van Zegeren")
PlayerLastName.Add("Bibbs")
PlayerLastName.Add("Muller")
PlayerLastName.Add("Pierce")
PlayerLastName.Add("Henry")
PlayerLastName.Add("Johnston")
Dim Players = From Last In PlayerLastName
Order By Last Ascending
Select Last
cboPlayer.Items.Add(Players.ToString)
cboPlayer.SelectedItem = 0
I know this isn't exactly correct but not positive what direction to head in. When I run the program the combo box is populated with System.linq.enumerated.
Any ideas what that might mean or what I am doing incorrectly?
Maybe over thinking it just a little? Why not try without the linq, List has a sort function. Also just bind PlayerLastName to the combobox.
Public Sub GetPlayers()
Dim PlayerLastName As New List(Of String)
PlayerLastName.Add("Smith")
PlayerLastName.Add("Hill")
PlayerLastName.Add("Beyer")
PlayerLastName.Add("Wilson")
PlayerLastName.Add("Hudson")
PlayerLastName.Add("van Zegeren")
PlayerLastName.Add("Bibbs")
PlayerLastName.Add("Muller")
PlayerLastName.Add("Pierce")
PlayerLastName.Add("Henry")
PlayerLastName.Add("Johnston")
PlayerLastName.Sort()
cboPlayers.DataSource = PlayerLastName
cboPlayers.SelectedIndex = -1
End sub
Edit:
or if you still want to us linq then, you need to change the linq return of IEnumerable to a List...
Dim Players = From Last In PlayerLastName
Order By Last Ascending
Select Last
ComboBox1.DataSource = Players.ToList
ComboBox1.SelectedIndex = -1

Checking duplicate Values on DataGrid

I have a DataGrid which is bound with a DataTable having two columns which store sequences, in my DataGrid these sequence columns are bound with DataGridViewComboBoxes. User is able to set sequence from ComboBoxes. Default values in sequence columns is 0.
I just want to check duplicacy in both the columns on button click, user should not be able select any duplicate value in both the columns.
If i implement it by using ToTable method of DataView to find distinct values it also takes rows with value "0"
if i implement unique constraint on column on DataTable it also checks for 0.
If try to remove values with 0 it also changes DataGrid As DataGrid is bound with DataTable
If i try to declare a new DataTable from existing dataTable it also gets bound to DataGrid Automatically.
Please help me.
Here is an example of how you can check for duplicate values in a DataTable:
Option Strict On
Module Module1
Sub Main()
Dim dt As New DataTable
dt.Columns.Add("mycolumn", GetType(Integer))
dt.Rows.Add({"1"})
dt.Rows.Add({"2"})
dt.Rows.Add({"2"})
dt.Rows.Add({"4"})
dt.Rows.Add({"7"})
Dim duplicateDictionary As New Dictionary(Of Integer, Integer) 'value, count
For Each row As DataRow In dt.Rows
Dim count As Integer = 0
Dim value As Integer = CInt(row("mycolumn"))
duplicateDictionary.TryGetValue(value, count)
duplicateDictionary(value) = count + 1
Next
For Each kv As KeyValuePair(Of Integer, Integer) In duplicateDictionary
If kv.Value > 1 Then 'we have a duplicate
Debug.WriteLine("{0} is a duplicated value, encountered {1} times", kv.Key, kv.Value)
End If
Next
End Sub
End Module
Adding a UniqueConstraint is possible as well, but I find it too intrusive at times, depending on how your editing works. For direct in-grid editing, you may want the user to save a non-valid record in memory, and allow to fix the error, showing validation errors instead of constraint violation exception. Of course you never save invalid data to the database.