How toI convert a Data gridview column to a list of strings? - vb.net

I'm trying to convert the first column from a Data Grid View to a list of string, then search through the list and highlight the corresponding row in red.
This is what I currently have
Dim search As String = txtsearch.Text
Dim lsttitlesort As New List(Of String)()
For i = 0 To dgvbooks.Rows.Count - 1
lsttitlesort.Add(dgvbooks(0, i).Value)
Next
For i As Integer = 1 To lsttitle.Count - 1
If lsttitlesort(i).ToLower.Contains(search.ToLower) Then
dgvbooks.Rows(i).DefaultCellStyle.BackColor = Color.Red
End If
Next
The problem is that when I try to run it, it crashes and displays an error message saying
System.NullReferenceException: 'Object reference not set to an instance of an object.'
I'm new to Data Grid Views: can you explain me how to fix it?

You can search directly on the DataGridView without using a list:
Dim search As String = txtsearch.Text
'iterate through all rows of the DataGridView to search the value.
For Each dgrBook As DataGridViewRow In dgvbooks.Rows
'you can skip the new row at the end (if available).
If dgrBook.IsNewRow Then
Continue For
End If
'check if first column contains the search value.
'if search value found on first column set the background color to red,
'otherwise reset the background to white.
If CStr(dgrBook.Cells(0).Value & "").ToLower.Contains(search.ToLower) Then
dgrBook.DefaultCellStyle.BackColor = Color.Red
Else
dgrBook.DefaultCellStyle.BackColor = Color.White
End If
Next

Related

Control name from Variable or Dataset. (Combobox)(.items.add)(.datasource)

I've checked for hours but I can't seem to find anything to help.
I want to loop through tables and columns from a dataset and use the column name in a combobox.items.add() line, however the eventual goal is to fill the combobox from the dataset itself possibly in a combobox.datasource line.
The first problem is that I can't get the code correct to setup the combobox control where it allows me to use .items.add("") and in extension .datasource
Error Message = "Object reference not set to an instance of an object"
dstcopt is the dataset from a oledbDataAdapter .fill(dstcopt,"table") line (which returns correct values)
tc_opt is a tab name on a tab control where the comboboxes are
For Each dstable In dstcopt.Tables
For Each dscolumn In dstable.Columns
Dim colName As String = dscolumn.ToString
MsgBox(colName) 'This retuns "aantigen"
Dim cb As ComboBox = Me.tc_opt.Controls("cb_" & colName)
cb.Items.Add(colName)
'cb_aantigen.DataSource = dstcopt.Tables(dstable.ToString)
'cb_aantigen.DisplayMember = "aantigen"
'cb_atarget.DataSource = dstcopt.Tables(dstable.ToString)
'cb_atarget.DisplayMember = "atarget"
Next
Next
The second problem comes when I do it manually (which works) using the exact combobox names cb_aantigen and cb_atarget as seen in the comments.
The problem is that once the form is loaded and the cb's are filled with the correct values, I can't change the value in any single cb individually, when I change one value it changes them all (there is 15 comboboxes in total) I know this is down to using a dataset, but I don't know away to 'unlink them from each other or the dataset'
Not sure if I need to split this into 2 questions, but help on either problem would be appreciated.
EDIT:
After looking at only this section of code for a day. This is what I have come up with to tackle both the problems at once.
The combobox control not working was down to using a tab tc_opt instead of a groupbox gp_anti
The issue with splitting the dataset up into individual comboboxes, I've worked around by taking the value of each cell in the database and adding it separately, probably a better way to do it though
For Each dstable As DataTable In dstcopt.Tables
For Each dscolumn As DataColumn In dstable.Columns
Dim colName As String = dscolumn.ToString
Dim cb(2) As ComboBox
cb(0) = CType(Me.gp_anti.Controls("cb_" & colName), ComboBox)
cb(1) = CType(Me.gp_rec.Controls("cb_" & colName), ComboBox)
cb(2) = CType(Me.gp_nat.Controls("cb_" & colName), ComboBox)
For icb = 0 To cb.Count - 1
If Not (IsNothing(cb(icb))) Then
For irow = 0 To dstable.Rows.Count - 1
If dstable.Rows(irow)(colName).ToString <> Nothing Then
Dim icbitemdupe As Boolean = False
If cb(icb).Items.Contains(dstable.Rows(irow)(colName).ToString) Then
icbitemdupe = True
End If
If icbitemdupe = False Then
cb(icb).Items.Add(dstable.Rows(irow)(colName).ToString)
End If
End If
Next
End If
Next
Next
Next

Search Datagridview Vb.net

I have been stuck in creating search for Datagridview in Vb.net.
I have one DataGridView that is bound to binding source. It contains data such as:
123456,
213926,
285643,
395687,
I have searched but everywhere but I only found a filter method for binding source or a find method.
The filter method removes remaining rows & find method finds an exact string.
I found a method to find text in DataGridView but that search found the string anywhere in DataGridView column like if user type 2 then it will first select the row having 2 such as 123456.
I want to create search that should find letter in sequence from start & so on.
If the user presses 2 then search should go for cell starting with 2 such as 213926.
Matter solved Frank. Thankyou So Much.
Here is my complete code for others too.
Dim Found As Boolean = False
Dim StringToSearch As String = ""
Dim ValueToSearchFor As String = Me.TextBox1.Text.Trim.ToLower
Dim CurrentRowIndex As Integer = 0
Try
If dgvDishonourReceipts.Rows.Count = 0 Then
CurrentRowIndex = 0
Else
CurrentRowIndex = dgvDishonourReceipts.CurrentRow.Index + 1
End If
If CurrentRowIndex > dgvDishonourReceipts.Rows.Count Then
CurrentRowIndex = dgvDishonourReceipts.Rows.Count - 1
End If
If dgvDishonourReceipts.Rows.Count > 0 Then
For Each gRow As DataGridViewRow In dgvDishonourReceipts.Rows
StringToSearch = gRow.Cells(4).Value.ToString.Trim.ToLower
If InStr(1, StringToSearch, LCase(Trim(TextBox1.Text)), vbTextCompare) = 1 Then
Dim myCurrentCell As DataGridViewCell = gRow.Cells(4)
Dim myCurrentPosition As DataGridViewCell = gRow.Cells(0)
dgvDishonourReceipts.CurrentCell = myCurrentCell
CurrentRowIndex = dgvDishonourReceipts.CurrentRow.Index
Found = True
End If
If Found Then Exit For
Next
End If
Catch ex As Exception
MsgBox(ex.ToString)
End Try

Datagridview Change cell color of non empty cell

Im creating a calendar appointment application, Id like to change the color of the datagridview of the non empty cell (those with value) upon loading/opening the application.
my application already handles how to load the data.
i'm able to change the color of the non empty cell but after closing and opening again the color is back to default.
Im not sure with the correct syntax , or if i need to go through all the cells like do a loop for the entire table and change the cell back color.
VB.net 2012
so my questions is like or the loop i wanted to attain is ;
if the cell is not empty then change cell.color
thanks for any help.
I manage to solve it:
Dim dgv As DataGridView = Me.TblCalendarDataGridView
For i As Integer = 0 To dgv.Rows.Count - 1
For ColNo As Integer = 4 To 7
If Not dgv.Rows(i).Cells(ColNo).Value Is DBNull.Value Then
dgv.Rows(i).Cells(ColNo).Style.BackColor = vbcolor.blue
End If
Next
Next
'try this.........
For i As Integer = 0 To DtGrd.Rows.Count - 1
For ColNo As Integer = 4 To 7
If Not DtGrd.Rows(i).Cells(ColNo).Value Is DBNull.Value Then
DtGrd.Rows(i).Cells(ColNo).Style.BackColor = Color.Red
End If
Next
Next

Make particular column as combo box of DataGridView

I just want to make Data Grid. Where first and second column of data grid is for storing single value and third column as combo box.
The code that i tried is
Dim productGrid As New DataGridView
ProductGrid.Columns(0).Name = "CB"
ProductGrid.Columns(1).Name = "ProductGroup"
ProductGrid.Columns(2).Name = "Product"
Dim i As Integer
With ProductGrid
If .Rows.Count = 0 Then Exit Sub
i = 1
Dim objValueItems As New DataGridViewComboBoxCell
objValueItems.Items.Add("Server")
objValueItems.Items.Add("Standalone")
objValueItems.Items.Add("Demo")
objValueItems.Items.Add("Anywhere")
ProductGrid.Item(2, i).Value = objValueItems
End With
I am getting the error on "ProductGrid.Item(2, i).Value = objValueItems" this line. Error is " Index was out of range.
Bear in mind that all the cells of a ComboBox DGV Column have the same contents, thus you are not assigning a list of items to a given cell, but to all of them (to a column). You have to include this when adding the given column. Sample code:
Dim productGrid As New DataGridView
With productGrid
.Columns.Add("CB", "CB") 'Text-type column
.Columns.Add("ProductGroup", "ProductGroup") 'Text-type column
Dim objValueItems As New DataGridViewComboBoxColumn
With objValueItems
.Name = "Product"
.Items.Add("Server")
.Items.Add("Standalone")
.Items.Add("Demo")
.Items.Add("Anywhere")
End With
.Columns.Add(objValueItems) 'ComboBox-type column
End With

Adding two column values to listbox in vb.net

I have a table named users which has the following columns in it
User_id,user_name,user_pwd,First_Name,Middle_Name,Last_Name and user_type.
I have dataset named dst and created a table called user in the dataset. Now I want to populate listbox with user_Name, First_Name, Last_name of each and every row in the table user.
I am able to add one column value at a time but not getting how to add multiple column values of each row to listbox
Dim dt As DataTable = Dst.Tables("user")
For Each row As DataRow In dt.Rows
lstUsers.Items.Add(row("User_Name"))
Next
Above code works perfectly but I also want to add First_name as well as last_name to the list box at the same time.
Use same approach as you have, but put all values you want in one string.
Dim dt As DataTable = Dst.Tables("user")
For Each row As DataRow In dt.Rows
Dim sItemTemp as String
sItemTemp = String.Format("{0},{1},{2}", row("User_Name"), row("First_Name"), row("Last_Name"))
lstUsers.Items.Add(sItemTemp)
Next
String.Format() function will call .ToString() on all parameters.
In this case if row(ColumnName) is NULL value then .ToString() return just empty string
You have 2 choices:
Using the ListBox:
To use the ListBox, set the font to one that is fixed width like courier new (so that the columns line up), and add the items like this:
For Each row As DataRow In dt.Rows
lstUsers.Items.Add(RPAD(row("User_Name"),16) & RPAD(row("First_Name"),16) & RPAD(row("Last_Name"),16))
Next
The RPAD function is defined like this:
Function RPAD(a As Object, LENGTH As Object) As String
Dim X As Object
X = Len(a)
If (X >= LENGTH) Then
RPAD = a : Exit Function
End If
RPAD = a & Space(LENGTH - X)
End Function
Adjust the LENGTH argument as desired in your case. Add one more for at least one space. This solution is less than ideal because you have to hard-code the column widths.
Use a DataGridView control instead of a ListBox. This is really the best option, and if you need, you can even have it behave like a ListBox by setting the option to select the full row and setting CellBorderStyle to SingleHorizontal. Define the columns in the designer, but no need to set the widths - the columns can auto-size, and I set that option in the code below. if you still prefer to set the widths, comment out the AutoSizeColumnsMode line.
The code to set up the grid and add the rows goes like this:
g.Rows.Clear() ' some of the below options are also cleared, so we set them again
g.AutoSizeColumnsMode = DataGridViewAutoSizeColumnMode.AllCells
g.CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal
g.SelectionMode = DataGridViewSelectionMode.FullRowSelect
g.AllowUserToAddRows = False
g.AllowUserToDeleteRows = False
g.AllowUserToOrderColumns = True
For Each row As DataRow In dt.Rows
g.Rows.Add(row("User_Name"), row("First_Name"), row("Last_Name"))
Next
You might solved your problem by now but other users like me might have issue with it.
Above answers given worked for me even but I found a same answer in a simple way according to what I want..
cmd = New SqlCommand("select User_Name, First_Name, Last_Name from User")
Dim dr As SqlDataReader = cmd.ExecuteReader(YourConnectionString)
If dr.HasRows Then
Do While dr.Read
lst.Items.Add(dr.Item(0).ToString & " " & dr.Item(1).ToString & " " & dr.Item(2).ToString)
Loop
End If
This worked for me, maybe wrong way but I found it simple :)
May I suggest you use a ListView control instead of Listbox?
If you make the switch, here's a sample subroutine you could use to fill it up with the data you said you want. Adapt it the way you like; there's much room for improvement but you get the general idea:
Public Sub FillUserListView(lstUsers As ListView, Dst As DataSet)
Dim columnsWanted As List(Of String) = New List(Of String)({"User_Name", "First_Name", "Last_Name"})
Dim dt As DataTable = Dst.Tables("user")
Dim columns As Integer = 0
Dim totalColumns = 0
Dim rows As Integer = dt.Rows.Count
'Set the column titles
For Each column As DataColumn In dt.Columns
If columnsWanted.Contains(column.ColumnName) Then
lstUsers.Columns.Add(column.ColumnName)
columns = columns + 1
End If
totalColumns = totalColumns + 1
Next
Dim rowObjects(columns - 1) As ListViewItem
Dim actualColumn As Integer = 0
'Load up the rows of actual data into the ListView
For row = 0 To rows - 1
For column = 0 To totalColumns - 1
If columnsWanted.Contains(dt.Columns(column).ColumnName) Then
If actualColumn = 0 Then
rowObjects(row) = New ListViewItem()
rowObjects(row).SubItems(actualColumn).Text = dt.Rows(row).Item(actualColumn)
Else
rowObjects(row).SubItems.Add(dt.Rows(row).Item(actualColumn))
End If
lstUsers.Columns.Item(actualColumn).Width = -2 'Set auto-width
actualColumn = actualColumn + 1
End If
Next
lstUsers.Items.Add(rowObjects(row))
Next
lstUsers.View = View.Details 'Causes each item to appear on a separate line arranged in columns
End Sub