Display image from database in a datagrid with vb.net - vb.net

I'm using a MySql database with 2 fields: a dossiernumber and a field where I save the name and location of a image. I want to place a datagrid on my winform and show a image (thumbnail) in the first cell and the dossiernumber in the second cell, but can't get it working.
The pictures don't show and leave only missing picture link. I also can't place the picture in the first cell. This is what it looks like:
What is wrong?
This is the code I've written:
Imports MySql.Data.MySqlClient
Public Class Form1
'ALLES OM DATAGRID TE PLAATSEN
'GLOBALE DECLARATIES
Dim conString As String = "server=localhost;userid=root;database=testvehicle"
Dim con As New MySqlConnection(conString)
Dim cmd As MySqlCommand
Dim adapter As MySqlDataAdapter
Dim dt As New DataTable()
Private Sub Form1_GotFocus(sender As Object, e As EventArgs) Handles Me.GotFocus
retrieve()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
DataGridView1.ColumnCount = 2
DataGridView1.Width = 410
'CONSTRUCT IMAGE COLUMN
Dim imgCol As DataGridViewImageColumn = New DataGridViewImageColumn()
DataGridView1.Columns(0).Name = "Image"
DataGridView1.Columns.Add(imgCol)
'CONSTRUCT DATA COLUMNS
DataGridView1.Columns(1).Name = "dossiernr"
DataGridView1.Columns(1).Width = 100
DataGridView1.SelectionMode = DataGridViewSelectionMode.FullColumnSelect
End Sub
'ALLES OM DATAGRID TE VULLEN
'PROCEDURE POPULATE ROW
Private Sub populate(foto1 As String, product_dossiernr As String)
Dim row As String() = New String() {foto1, product_dossiernr}
'ADD ROW TO ROWS
DataGridView1.Rows.Add(row)
End Sub
'DATA ONTVANGEN
Private Sub retrieve()
DataGridView1.Rows.Clear()
'SQL STATEMENT
Dim sql As String = "SELECT foto1, product_dossiernr FROM producten ORDER BY product_dossiernr"
cmd = New MySqlCommand(sql, con)
'OPEN CON, RETRIEVE, FILL DATAGRID
Try
con.Open()
adapter = New MySqlDataAdapter(cmd)
adapter.Fill(dt)
For Each row In dt.Rows
populate(row(0), row(1))
Next
con.Close()
dt.Rows.Clear()
Catch ex As Exception
MsgBox(ex.Message)
con.Close()
End Try
End Sub
'EINDE DATAGRID VULLEN
End Class

in your code it looks like your naming your column the image name, not assigning it a picture value so this is why your getting the name and not the image.
here is s snippet of code I used before that works pretty well.
Dim ColImage As New DataGridViewImageColumn
Dim Img As New DataGridViewImageCell
'Set Name
ColImage.Name = "ColImg"
'Set Header text
ColImage.HeaderText = "Your Image!"
'Add column to datagridview
DataGridView1.Columns.Add(ColImage)
'Set image value
Img.Value = Image.FromFile("C:\YourImage.png")
'Add the image cell to a row
DataGridView1.Rows(0).Cells.Add(Img)

Related

How can I write a loop to replace this if statement for different buttons

I have an Access datatable named A. It has 90 rows and each row has 2 columns as follows:
I have a vb form that has 90 green buttons and code:
Private Sub _1st_Floor_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim myConnection As New OleDbConnection(myConnString)
Dim myCommand As New OleDbCommand("SELECT ID FROM A WHERE Busy=True", myConnection)
myConnection.Open()
Dim reader As OleDbDataReader
Dim dt As New DataTable
dt.Load(myCommand.ExecuteReader)
If dt.Rows(0).Item(0).ToString = 1 Then
Button1.BackColor = Color.Red
Button1.FlatAppearance.BorderColor = Color.Red
End If
If dt.Rows(1).Item(0).ToString = 2 Then
Button2.BackColor = Color.Red
Button2.FlatAppearance.BorderColor = Color.Red
End If
End Sub
This works fine, but I don't want to repeat the same If block over and over again for 90 buttons. How can I write a loop with just one set of code for all 90 buttons?
Loop through your records and find the corresponding buttons:
For Each row As DataRow In dt.Rows
Dim buttonName as String = "button" & row(0).ToString()
Dim cntrls() As Control = Me.Controls.Find(buttonName, True)
If cntrls IsNot Nothing Then
Dim btn As Button = TryCast(cntrls(0), Button)
If btn IsNot Nothing Then
btn.BackColor = Color.Red
btn.FlatAppearance.BorderColor = Color.Red
End If
End If
Next
This is dependent on the buttons' naming scheme being consistent.
Using your own "words" :) maybe not the most efficient way but I just wanted to write this by reusing your code as much as possible...
Private Sub _1st_Floor_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim myConnection As New OleDbConnection(myConnString)
Dim myCommand As New OleDbCommand("SELECT ID FROM A WHERE Busy=True", myConnection)
myConnection.Open()
Dim reader As OleDbDataReader
Dim dt As New DataTable
dt.Load(myCommand.ExecuteReader)
For index As Integer = 1 To 90
If dt.Rows(index - 1).Item(0).ToString = index.ToString Then
Dim button As Button = CType(Me.Controls("Button" + index.ToString), Button)
button.BackColor = Color.Red
button.FlatAppearance.BorderColor = Color.Red
End If
Next
End Sub
I used this post to get controls by name String

ListBox index changed shows wrong value from SQLite database

I am coding a VB.NET program, which uses SQLite as a database.
My problem is when the form is loading it is displaying all values from a particular column (questions in my case) from the database to the ListBox. Then if the user clicks on any item (ListBox index change), the corresponding value from the database (answer) displays in a RichTextBox. This works as expected.
When the user types something in a TextBox and clicks the search Button, it is expected to show the questions from the database according to TextBox.Text as a tag column in the database to the same ListBox. This also works fine.
The problem begins when the ListBox index changes now. If the search result is only one item in the ListBox, the index will be zero and the RichTextBox shows the first item of the database insted of the corresponding value of the ListBox item.
My code is here:
Sub showData()'''this shows questions when form loads
connect()
Dim da As New SQLiteDataAdapter("select * from elect", connection)
'Dim dt As New DataTable
Dim ds As New DataSet
da.Fill(ds, "elect")
Dim mySelectQuery As String = "select * from elect"
Dim sqConnection As New SQLiteConnection(connection)
Dim sqCommand As New SQLiteCommand(mySelectQuery, sqConnection)
'sqConnection.Open()
Try
Dim sqReader As SQLiteDataReader = sqCommand.ExecuteReader()
' Always call Read before accessing data.
Do While sqReader.Read()
Dim sName = sqReader.Item("question")
ListBox1.Items.Add(sName)
Loop
' always call Close when done reading.
sqReader.Close()
' Close the connection when done with it.
Finally
connection.Close()
End Try
End Sub
Public Sub NavigateRecords()
page1.Clear()''page is rich text box
connect()
Dim da As New SQLiteDataAdapter("select * from elect", connection)
'Dim dt As New DataTable
Dim ds As New DataSet
da.Fill(ds, "elect")
Dim mySelectQuery As String
mySelectQuery = "select * from elect"
Dim sqConnection As New SQLiteConnection(connection)
Dim sqCommand As New SQLiteCommand(mySelectQuery, sqConnection)
Dim num As Integer = Me.inc = Conversions.ToInteger(ListBox1.SelectedIndices.ToString)
MsgBox(num)
Me.inc = Conversions.ToInteger(ListBox1.SelectedIndex.ToString)
If (Me.inc > -1) Then
Dim ans As String = Conversions.ToString(ds.Tables.Item("elect").Rows.Item(Me.inc).Item(2))
page1.Text = (ans)
End If
End Sub
Private Sub search()
connect()
Dim da As New SQLiteDataAdapter("select * from elect", connection)
'Dim dt As New DataTable
Dim ds As New DataSet
da.Fill(ds, "elect")
Dim mySelectQuery As String = ("select * from elect WHERE tag like'%" & txtSearch.Text & "%' ")
Dim sqConnection As New SQLiteConnection(connection)
Dim sqCommand As New SQLiteCommand(mySelectQuery, sqConnection)
Try
Dim sqReader As SQLiteDataReader = sqCommand.ExecuteReader()
' Always call Read before accessing data.
Do While sqReader.Read()
Dim sName = sqReader.Item("question")
ListBox1.Items.Add(sName)
Loop
If ListBox1.Items.Count = 0 Then
MsgBox("Nothing Found ")
showData()
End If
' always call Close when done reading.
sqReader.Close()
' Close the connection when done with it.
Finally
connection.Close()
End Try
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
page1.Visible = True
ListBox1.Visible = False
Label1.Visible = False
NavigateRecords()
End Sub

Flat multi-column combobox - filling columns with DB tables

I found a very good free multi-column combobox, but can't fill second column with It, so far I managed to display only 1 column. Does anybody have any experience doing this via Datable - It has to be done like this, at least auhors of control claim so. Here is my code:
EDIT:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim SQL As String = "SELECT Name,Surname from MyTable"
Dim dtb As New DataTable
dtb.Columns.Add("Name", System.Type.GetType("System.String"))
dtb.Columns.Add("Surname, System.Type.GetType("System.String"))
Using con As OracleConnection = New OracleConnection("Data Source=MyDB;User Id=Lucky;Password=MyPassword;")
Try
con.Open()
Using dad As New OracleDataAdapter(SQL, con)
dad.Fill(dtb)
End Using
MtgcComboBox1.ColumnNum = 2
MtgcComboBox1.LoadingType = MTGCComboBox.CaricamentoCombo.DataTable
MtgcComboBox1.SourceDataString = {"Name", "Surname"}
MtgcComboBox1.SourceDataTable = dtb
con.Close()
Catch ex As Exception
'MessageBox.Show(ex.Message)
Finally
con.Dispose()
End Try
End Using
And here is link for control - some instructions there too :
http://www.codeproject.com/Articles/8619/Flat-MultiColumn-Combobox-with-Autocomplete
This is simplified version of the answer in Any way for a combo box with 2 values per line?
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dtb As New DataTable
Using dad As New OracleDataAdapter("SELECT Name,Surname from MyTable", "Data Source=MyDB;User Id=Lucky;Password=MyPassword;")
dad.Fill(dtb) ' this should add the columns
End Using
Dim items = From r In dtb.Rows.Cast(Of DataRow) r(0).ToString & vbNullChar & r(1).ToString
ComboBox1.DrawMode = DrawMode.OwnerDrawFixed
ComboBox1.DataSource = items.ToList
'ComboBox1.DisplayMember = "Name"
'ComboBox1.ValueMember = "Surname"
End Sub
Private Sub ComboBox1_DrawItem(sender As Object, e As DrawItemEventArgs) Handles ComboBox1.DrawItem
e.DrawBackground() ' Fill the background.
Dim items = ComboBox1.Items(e.Index).ToString.Split(ControlChars.NullChar) ' Extract the Record object corresponding to the combobox item to be drawn.
Dim loc = e.Bounds.Location, xMid = (loc.X + e.Bounds.Width - loc.X) \ 2 ' Calculate important positions based on the area of the drop-down box.
TextRenderer.DrawText(e.Graphics, items(0), e.Font, loc, e.ForeColor) ' Draw the first (Unique ID) string in the first half.
TextRenderer.DrawText(e.Graphics, items(1), e.Font, New Point(xMid + 5, loc.Y), e.ForeColor) ' Draw the second (Name) string in the second half, adding a bit of padding.
e.Graphics.DrawLine(SystemPens.ButtonFace, xMid, loc.Y, xMid, loc.Y + e.Bounds.Height) ' optional Draw the column separator line right down the middle.
e.DrawFocusRectangle() ' Finally, draw the focus rectangle.
End Sub
I think you're just missing the instructions to show the columns. From the example:
MtgcComboBox1.LoadingType = MTGCComboBox.CaricamentoCombo.DataTable
MtgcComboBox1.SourceDataString = {"Name", "SurName"}
MtgcComboBox1.ColumnWidth = "100;100"
MtgcComboBox1.SourceDataTable = dtb

ListView in VB.NET (VS 2010)

I am trying to display sql database table data in a list view in my vb application. I have used the following code
Public Class Form1
Dim conn As SqlClient.SqlConnection
Dim cmd As SqlClient.SqlCommand
Dim da As SqlClient.SqlDataAdapter
Dim ds As DataSet
Dim itemcoll(100) As String
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.ListView1.View = View.Details
Me.ListView1.GridLines = True
conn = New SqlClient.SqlConnection("Data Source=AYYAGARI-PC\WINCC;Initial Catalog=anand;Integrated Security=True")
conn.Open()
Dim strQ As String = String.Empty
strQ = "SELECT * FROM [anand].[dbo].[WINCC] ORDER BY [dateandtime]"
cmd = New SqlClient.SqlCommand(strQ, conn)
da = New SqlClient.SqlDataAdapter(cmd)
ds = New DataSet
da.Fill(ds, "Table")
Dim i As Integer = 0
Dim j As Integer = 0
' adding the columns in ListView
For i = 0 To ds.Tables(0).Columns.Count - 1
Me.ListView1.Columns.Add(ds.Tables(0).Columns(i).ColumnName.ToString())
Next
'Now adding the Items in Listview
Try
Call Timer1_Tick(sender, e)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
For Each i As ListViewItem In ListView1.SelectedItems
ListView1.Items.Remove(i)
Next
Try
For i = 0 To ds.Tables(0).Rows.Count - 1
For j = 0 To ds.Tables(0).Columns.Count - 1
itemcoll(j) = ds.Tables(0).Rows(i)(j).ToString()
Next
Dim lvi As New ListViewItem(itemcoll)
Me.ListView1.Items.Add(lvi)
Next
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
The problem with the above code is that whenever i update the table data in sql (inserting or deleting data), the same doesnt get updated in list view. Kindly help me out with this.
Me.ListView1.View = View.Details
Me.ListView1.GridLines = True
conn = New SqlClient.SqlConnection("Data Source=AYYAGARI-PC\WINCC;Initial Catalog=anand;Integrated Security=True")
conn.Open()
Dim strQ As String = String.Empty
strQ = "SELECT * FROM [anand].[dbo].[WINCC] ORDER BY [dateandtime]"
cmd = New SqlClient.SqlCommand(strQ, conn)
da = New SqlClient.SqlDataAdapter(cmd)
ds = New DataSet
da.Fill(ds, "Table")
Dim i As Integer = 0
Dim j As Integer = 0
' adding the columns in ListView
For i = 0 To ds.Tables(0).Columns.Count - 1
Me.ListView1.Columns.Add(ds.Tables(0).Columns(i).ColumnName.ToString())
Next
'Now adding the Items in Listview
Try
Call Timer1_Tick(sender, e)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
Try to add this code again to your button which made insert or update.
UPDATE
I give you another tips, that wont make your code so long and wasted memory or capacity..
Try to insert all the code to new sub, e.g :
private sub mycode
msgbox("Hello World")
end sub >> This code won't work when you debug, cause it just like a stored code, so need to be called to make it work
Private sub Form_load...... > E.g this is your form load code
call mycode >> Called the code above
end sub >> when you debug, your form will auto called the mycode

Showing all fields in listbox from database, vb.net

I'm trying to make a list box to show all the fields of a particular table in an Access database. I have a few tables, and the idea would be to have each table loaded by a different button (and the items in the box cleared). One trick is that tables aren't all the same size. How do I get all the fields to show up for each table. What I have now is only showing one field:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0;data source='C:\dummy_data.accdb';"
Dim conn As New OleDbConnection(connString)
Dim sql As String = "SELECT * FROM Customers"
Dim cmd As New OleDbCommand(sql, conn)
conn.Open()
Dim reader As OleDbDataReader = cmd.ExecuteReader()
ClientList.Items.Clear()
While reader.Read()
ClientList.Items.Add(reader(0).ToString())
End While
reader.Close()
conn.Close()
End Sub
If you are not averse to using a DataGridView instead of a ListView, you could do it this way:
Dim connString As String = "Provider=Microsoft.Jet.OLEDB.4.0;data source='PathToMyDatabase';"
Dim sql As String = "SELECT * FROM Tメイン;"
Dim dt As DataTable
With New OleDbDataAdapter(sql, connString)
Dim ds As New DataSet()
.Fill(ds)
dt = ds.Tables(0)
End With
Me.DataGridView1.DataSource = dt
I do not have 'ACE.OLEDB' on my computer, so had to use the JET provider instead, but it should work the same way.
I should add that you can use this method to retrieve the data from the DB, but there is no easy way as far as I understand to bind a DataTable to a ListView (see this MSDN question for example) and you would have to loop through the columns in your DataTable first and add the column headers to your ListView and then loop through the rows and add the data.
UPDATE:
To answer your questiona s to how to export data from the DataGridView I remembered that I wrote code to do that a little while back.
Private Function ExportToExcelFile(ByVal FileName As String) As Boolean
With New Excel.Application
With .Workbooks.Add()
For Each sheet As Worksheet In .Worksheets
If sheet.Index > 1 Then
Call sheet.Delete()
End If
Next
With CType(.Worksheets(1), Worksheet).Range("A1")
For Each column As DataGridViewColumn In Me.dgvData.Columns
.Offset(0, column.Index).Value = column.HeaderText
For Each row As DataGridViewRow In Me.dgvData.Rows
.Offset(row.Index + 1, column.Index).Value = row.Cells(column.Index).Value
Next
Next
End With
Call .SaveAs(FileName)
End With
Call .Quit()
End With
End Function
I hope this will help to get you started.
Using a Listview control, the following code should do the trick. For simplicity I defined only 4 customer fields - you will need to define them according to your table field defintions:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ClientList.View = View.Details
ClientList.FullRowSelect = True
ClientList.Columns.Add("ID", 120)
ClientList.Columns.Add("Name", 120)
ClientList.Columns.Add("Address", 140)
ClientList.Columns.Add("Email", 100)
Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0;data source=C:\dummy_data.accdb;"
ClientList.Items.Clear()
Using conn As New Data.OleDb.OleDbConnection(connString)
conn.Open()
Dim sql As String = "SELECT * FROM Customers"
Using cmd As New Data.OleDb.OleDbCommand(sql, conn)
Dim lvi As ListViewItem
Using oRDR As Data.OleDb.OleDbDataReader = cmd.ExecuteReader
While oRDR.Read()
lvi = ClientList.Items.Add(oRDR.GetValue(0).ToString)
For i = 1 To oRDR.FieldCount - 1
lvi.SubItems.Add(oRDR.GetValue(i).ToString)
Next
End While
End Using
End Using
conn.Close()
End Using
End Sub