How to iterate display values in a combobox - vb.net

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

Related

Dataset with Datatable

I am trying to check if my dictionary contains values in my dataset.datatable and if its quantities in the second column of the dataset are less than or greater than the quantities in my datatable. I tried using the SELECT method but it doesn’t seem to work, I get the error BC30469 reference to non-shared member requires object reference?
I was just trying to do a simple search in the table first to see if I can even do that..... apparently not. Thanks for the help!
Dim row As DataRow = DataSet.DataTable.Select("ColumnName1 = 'value3'")
If Not row Is Nothing Then
searchedValue = row.Item("ColumnName2")
End If
You could get a dictionary to compare with the one you already have like this (assuming your key is a string and the amount an Int32 and that your dataset contains only one table):
Dim myDBDict As Dictionary(Of String, Int32) =
From e In myDataSet.Tables(0).Rows.Cast(Of DataRow).ToDictionary(Of String, Int32)(
Function(e) e.Field(Of String)("MyIDColumn"),
Function(e) e.Field(Of Int32)("myAmountColumn"))

Filter DataGridView across all columns

Sorry for my bad English. I am an old German man, I want to filter a DGV across all columns. In the Moment I use following filter:
Dim Such_Spalte = Me.DtS_DGV.DTT_1.article_1Column.ColumnName
But I have 10 Columns (article_1 to Article_10)
If as an example Sugar is in column 1,3,5 I want to see all records where sugar occurs.
I hope this is understandable
You seem to be using strongly typed datasets and as such I would expect that your datagridview is bound through a BindingSource (the windows forms designer sets it up this way, and my presumption is that you used te designer to do your binding)
If your datagridview is indeed bound through a bindingsource:
Dim bs = DirectCast(datagridviewX.DataSource, BindingSource)
Dim sb = New StringBuilder() 'it will hold the filter string
For Each col in DtS_DGV.DTT_1.Columns
sb.AppendFormat("[{0}] = '{1}' OR ", col.ColumnName, "Sugar")
Next col
sb.Length -= 3 'remove the trailing OR
bs.Filter = sb.ToString()
If your datagridview is bound direvtly to the table, it will have attached to the table's DefaultView property, a DataView, which also has a Filter that works in the same way. If this is the case, do the same thing with the loop to build the filter string, and then:
DtS_DGV.DTT_1.DefaultView.Filter = sb.ToString()

Won't add a default custom row on combobox

been having an issue displaying an empty item as default selected item on a combobox. This combobox is a filter for my gridview and currently my datagridview displays all data based on the first item of the combobox but what i wanted is to have an empty first combobox item so that datagridview will pull all data from database. When i run the app it says
System.ArgumentException: 'Input string was not in a correct
format.Couldn't store <> in ailment_id Column. Expected type is
Int32.'
My code to populate combobox from database:
Private Sub populateComboAilment()
data_adapter = New MySqlDataAdapter("SELECT * FROM ailment", myconnection.open())
Dim data_table As New DataTable
data_adapter.Fill(data_table)
'assign default value
Dim row As datarow = data_table.NewRow()
row(0) = ""
data_table.Rows.InsertAt(row, 0)
comboAilment.DataSource = data_table
With comboAilment
.DisplayMember = "name"
.ValueMember = "ailment_id"
End With
myconnection.close()
End Sub
Update: All is working now when I changed combobox ValueMember to a
name since it's an id before. but when I select another item it
displays nothing on the gridview because my datagridview query doesn't
know the name, only id since it's a foreign key.
Any help would be greatly appreciated!
Ah, I just looked more carefully at the code and you're not actually assigning a String containing "<>" but rather an empty String. It doesn't really matter though. A String is a String and you can't put one where a number is required. You might be able to use a String that contained digits because that could be implicitly converted to a number but a empty String doesn't qualify.
If you want an empty field in a DataRow then you need to do what ADO.NET does to represent a database null, i.e. use DBNull.Value. That means an object of type DBNull, which is required because ADO.NET predates nullable value types. You can't just use Nothing because would work for reference types but not value types, e.g. if you assign Nothing to an Integer variable you are effectively setting it to zero.
In short, you need to change this:
Dim row As datarow = data_table.NewRow()
row(0) = DBNull.Value
row(1) = DBNull.Value
data_table.Rows.InsertAt(row, 0)
In the case of the name column, its data type is String so you could use an empty String there (preferably String.Empty rather than "" but either works) but null is more appropriate because it is actually no value, rather than a value containing no characters.

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.