Display an image from datagridview to a picturebox - vb.net

Can anyone help me with this one? The scenario is that when I click any columns in a datagridview it will display the image to a picturebox
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
If e.RowIndex >= 0 Then
Dim row As DataGridViewRow
row = Me.DataGridView1.Rows(e.RowIndex)
lblProperty.Text = row.Cells("Column1").Value.ToString
txtType.Text = row.Cells("Column2").Value.ToString
txtPrice.Text = row.Cells("Column3").Value.ToString
txtBed.Text = row.Cells("Column4").Value.ToString
txtBath.Text = row.Cells("Column5").Value.ToString
txtFootages.Text = row.Cells("Column6").Value.ToString
txtStatus.Text = row.Cells("Column7").Value.ToString
txtYear.Text = row.Cells("Column8").Value.ToString
txtDesc.Text = row.Cells("Column9").Value.ToString
Dim bytes As [Byte]() = row.Cells("Column10").Value
Dim ms As New MemoryStream(bytes)
pbImage.Image = Image.FromStream(ms)
txtDate.Text = row.Cells("Column11").Value.ToString
txtAddress.Text = row.Cells("Column12").Value.ToString
txtStories.Text = row.Cells("Column13").Value.ToString
End If
End Sub
It has an error Unable to cast object of type 'System.String' to type 'System.Byte[]'.

Dim bytes As Byte() = Datagridview1.CurrentRow.Cells(5).Value
Using ms As New MemoryStream(bytes)
Picturebox1.Image = Image.FromStream(ms)
End Using

Maybe you are over thinking it, there is a function to easily draw bitmaps.
I would suggest using the DrawToBitmap on the DataGridView by using the ColumnBounds
example this:
Dim GridBitmap as new Bitmap(DataGridView1.GetColumnDisplayRectangle(row.Cells("Column10").ColumnIndex,false).width,DataGridView1.GetColumnDisplayRectangle(row.Cells("Column10").ColumnIndex,false).height)
DataGridView1.DrawToBitmap(GridBitmap,DataGridView1.GetColumnDisplayRectangle(row.Cells("Column10").ColumnIndex,false))
pbImage.Image = GridBitmap
It might need to be adapted to your DataGridView.
Note, Instead of this:
Dim bytes As [Byte]() = row.Cells("Column10").Value
Dim ms As New MemoryStream(bytes)
pbImage.Image = Image.FromStream(ms)
Still having problem? Try this:
New project.
Add a DataGridView (DataGridView1) to your form.
Add some random columns to your gridview.
Add a Picture Box to your form (PictureBox1)
Make sure the Picture box property "SizeMode" is set to auto size.
Add an event forDataGridView1.MouseDown.
Add this code to the event.
Dim GridBitmap As New Bitmap(DataGridView1.GetColumnDisplayRectangle(e.ColumnIndex, True).Width + DataGridView1.GetColumnDisplayRectangle(e.ColumnIndex, True).Left, DataGridView1.GetColumnDisplayRectangle(e.ColumnIndex, True).Height)
Dim GridColRectangle As New Rectangle(0, 0, DataGridView1.GetColumnDisplayRectangle(e.ColumnIndex, True).Width + DataGridView1.GetColumnDisplayRectangle(e.ColumnIndex, True).Left, DataGridView1.GetColumnDisplayRectangle(e.ColumnIndex, True).Height + DataGridView1.GetColumnDisplayRectangle(e.ColumnIndex, True).Top)
DataGridView1.DrawToBitmap(GridBitmap, GridColRectangle)
PictureBox1.Image = GridBitmap
You may need to adjust it to your own application.

Related

How to retrieve text from dynamic label and display it to message box using dynamic button?

I have these codes retrieving data from mysql database and display it into the dynamic panels, labels, and buttons. The problem is I don't know how to retrieve those texts from labels(lblProductName) to display it into message box when clicking the dynamic buttons(btnAddto). TIA!
Imports MySql.Data.MySqlClient
Module mdlMenu
Dim Cpanel As Panel
Dim lblProductName As Label
Dim btnAddto As Button
Dim count As Integer
Public Sub LoadMenu()
Try
SQLConnection()
With sqlcom
.CommandText = "SELECT * FROM tblproduct"
.Connection = sqlconn
End With
Dim datareader As MySqlDataReader = sqlcom.ExecuteReader
Do While datareader.Read()
Cpanel = New Panel()
With frmMenu
count = .TableLayoutPanel1.Controls.OfType(Of Panel)().ToList().Count
Cpanel.Location = New Point(10, (25 * count) * 7)
Cpanel.Size = New Size(450, 160)
Cpanel.Name = "Cpanel" & count
Cpanel.AutoScroll = True
Cpanel.BackColor = Color.White
.TableLayoutPanel1.Controls.Add(Cpanel)
lblProductName = New Label()
lblProductName.Location = New Point(165, 10)
lblProductName.AutoSize = True
lblProductName.Name = "lblProd" & count
lblProductName.Text = datareader.Item("ProductName").ToString & count
lblProductName.Font = New Font(lblProductName.Font.FontFamily, 14, FontStyle.Bold)
Cpanel.Controls.Add(lblProductName)
btnAddto = New Button()
btnAddto.Location = New Point(180, 115)
btnAddto.Size = New Size(80, 40)
btnAddto.Name = count
btnAddto.Text = count
btnAddto.Tag = count.ToString
btnAddto.Font = New Font(btnAddto.Font.FontFamily, 10, FontStyle.Bold)
AddHandler btnAddto.Click, AddressOf btnAddto_Click
Cpanel.Controls.Add(btnAddto)
count += 1
End With
Loop
Catch ex As Exception
MsgBox(ex.Message)
Finally
sqlconn.Close()
sqlconn.Dispose()
End Try
End Sub
There are a couple of concepts here:
How to reference a dynamic control
How to bind an event to a dynamic control
Regarding number 1 on how to reference a dynamic control, it looks like you are declaring a form level variable and setting the value. So you should be able to reference lblProductName after it is set in the LoadMenu method. However, if you did not want to create a form level variable, you could simply use the Controls.Find method (documentation).
Regarding number 2 on how to bind an event to a dynamic control, you would use the AddHandler statement (documentation), which it looks like you are already doing here:
AddHandler btnAddto.Click, AddressOf btnAddto_Click
So what would the btnAddto_Click method look like putting it all together?
Private Sub btnAddto_Click(sender As Object, e As EventArgs)
Dim button = DirectCast(sender, Button)
Dim count = If(button.Tag IsNot Nothing, button.Tag.ToString(), String.Empty)
Dim labels = Controls.Find("lblProd" & count, True)
If (labels.Length > 0) Then
Dim label = labels(0)
MessageBox.Show(label.Text)
End If
End Sub

Show image in vb.net

I'm trying to show a saved image in SQL Server but it gives me an error that says "parameter is not valid".
While oDataReader.Read()
TextBox1.Text = oDataReader("nombre")
Dim imagenbyte As Byte()
imagenbyte = oDataReader("imagen")
Dim mStream As New IO.MemoryStream()
mStream.Write(imagenbyte, 0, Convert.ToInt32(imagenbyte.Length))
Dim bm As Bitmap = New Bitmap(mStream, True)
PictureBox1.Image = bm
End While
You can consolidate that code down to this:
While oDataReader.Read()
TextBox1.Text = oDataReader("nombre")
Dim mStream As New IO.MemoryStream(oDataReader("imagen"))
PictureBox1.Image = Image.FromStream(mStream)
End While
The main fix here is using Image instead of Bitmap. And if you know you'll only have one record, you should change While to If. If you might have more than one record, you need to completely re-think some things in your user interface.

datagridview Image Display vb.net MS Access

my code is to read the image file path in every row and display it in the datagridview "Image" Column.
.....
what's the problem with my code? please help me fix this.
UPDATE
this is the updated code but it displays nothing.
Dim dbdataset As New DataTable
Try
con.Open()
query = "Select * FROM [svfmemberlist]"
cmd = New OleDbCommand(query, con)
da.SelectCommand = cmd
da.Fill(dbdataset)
dgvSearch.RowTemplate.Height = 150
source.DataSource = dbdataset
dgvSearch.DataSource = source
Dim img As New DataGridViewImageColumn()
dgvSearch.Columns.Add(img)
img.HeaderText = "Image"
img.Name = "img"
img.ImageLayout = DataGridViewImageCellLayout.Zoom
dgvSearch.Columns("img").DataGridView.AutoGenerateColumns = False
dgvSearch.Columns("Name").AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
dgvSearch.Columns("img").Width = 150
For Each row As DataGridViewRow In dgvSearch.Rows
If Not row.Cells("imgPath").FormattedValue.ToString = Nothing Then
Dim str As String = row.Cells("imgPath").FormattedValue.ToString
Dim inImg As Image = Image.FromFile(str)
row.Cells("img").Value = inImg
Else
img.Image = Nothing
End If
Next
con.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
The following example does not match how you are loading data and images but with a little effort will work within your current code.
I created two columns in the DataGridView via the IDE, one Text and one Image DataGridViewColumn.
The first line in form load sets ImageLayout, second line of code sets alignment to top-left for appearances. Next I set auto-size mode for all columns followed by setting the row height for each row.
Next (these lines are to load images from a folder one level below the app folder).
Setup the path to the images.
Add images using FileImageBytes function (which I would place into a separate class or code module but works just fine in your form).
Yes everything is hard-wired so it's easy to see how everything works.
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
CType(DataGridView1.Columns("PictureColumn"), DataGridViewImageColumn).ImageLayout = DataGridViewImageCellLayout.Normal
DataGridView1.Columns.Cast(Of DataGridViewColumn).Select(Function(col) col).ToList _
.ForEach(Sub(col) col.CellTemplate.Style.Alignment = DataGridViewContentAlignment.TopLeft)
DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
DataGridView1.RowTemplate.Height = 222
Dim imagePath As String = IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images")
DataGridView1.Rows.Add(New Object() {"Car1", FileImageBytes(IO.Path.Combine(imagePath, "Car1.bmp"))})
DataGridView1.Rows.Add(New Object() {"Car2", FileImageBytes(IO.Path.Combine(imagePath, "Car2.jpg"))})
End Sub
Public Function FileImageBytes(ByVal FileName As String) As Byte()
Dim fileStream As IO.FileStream = New IO.FileStream(FileName, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
Dim byteArray(CInt(fileStream.Length - 1)) As Byte
fileStream.Read(byteArray, 0, CInt(fileStream.Length))
Return byteArray
End Function
End Class

Datagridview CheckboxColumn Shaded or (X) Mark when unchecked

Good Morning
I have a column in DataGridView that generates checkbox and in relation to that I have also a lot of columns in my table that is called 2016,2017 and so on and all of that is TinyInt
Now here is the image for both of them:
Now here is my question, instead of uncheck how can make it shaded or X mark in the DataGridView Column?
here is my code in populating the DataGridView:
Dim sql1 As MySqlCommand = New MySqlCommand("Select * from period_closure", con1)
Dim ds1 As DataSet = New DataSet
Dim adapter1 As MySqlDataAdapter = New MySqlDataAdapter
con1.Open()
adapter1.SelectCommand = sql1
adapter1.Fill(ds1, "MyTable")
DataGridView1.DataSource = ds1.Tables(0)
con1.Close()
ds1.Tables(0).Columns(2).DataType = GetType(Boolean)
Me.DataGridView1.Columns(0).Frozen = True
Dim i As Integer
For i = 0 To DataGridView1.Columns.Count - 1
DataGridView1.Columns.Item(i).SortMode = DataGridViewColumnSortMode.Programmatic
Next
DataGridView1.Columns("PeriodID").Visible = False
DataGridView1.Columns(0).DefaultCellStyle.BackColor = Color.LightBlue
First of all download 'X' image in google, or create your own.
then try to add this in your code.
Private Sub CheckBox1_Paint(sender As Object, e As PaintEventArgs) Handles CheckBox1.Paint
If CheckBox1.Checked = False Then
Try
Dim newImage As Image = Image.FromFile("E:\Projects\Library\BER-X.jpg")
Dim x As Single = 0
Dim y As Single = 0
Dim width As Single = CheckBox1.Width 'You can also try this CheckBox1.Width - 3
Dim height As Single = CheckBox1.Height 'You can also try this CheckBox1.Height - 3
e.Graphics.DrawImage(newImage, x, y, width, height)
Catch ex As Exception
End Try
End If
End Sub
the X mark in the checkbox is not accurate in the position but you can fix it by your self. Try it and Explore it to fit it in your system. :)
Hope this will help you.

Crop image and save it in database using vb.net

I'm following a tutorial on Image Cropping with resizing using vb.net . Everything works well, But instead of saving it
on the hard disk. I want to save it on my database(SQLServer).
This is the code of saving on a disk
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cropSaveBtn.Click
Dim tempFileName As String
Dim svdlg As New SaveFileDialog()
svdlg.Filter = "JPEG files (*.jpg)|*.jpg|All files (*.*)|*.*"
svdlg.FilterIndex = 1
svdlg.RestoreDirectory = True
If svdlg.ShowDialog() = Windows.Forms.DialogResult.OK Then
tempFileName = svdlg.FileName 'check the file exist else save the cropped image
Try
Dim img As Image = PreviewPictureBox.Image
SavePhoto(img, tempFileName, 225)
Catch exc As Exception
MsgBox("Error on Saving: " & exc.Message)
End Try
End If
End Sub
Public Function SavePhoto(ByVal src As Image, ByVal dest As String, ByVal w As Integer) As Boolean
Try
Dim imgTmp As System.Drawing.Image
Dim imgFoto As System.Drawing.Bitmap
imgTmp = src
imgFoto = New System.Drawing.Bitmap(w, 225)
Dim recDest As New Rectangle(0, 0, w, imgFoto.Height)
Dim gphCrop As Graphics = Graphics.FromImage(imgFoto)
gphCrop.SmoothingMode = SmoothingMode.HighQuality
gphCrop.CompositingQuality = CompositingQuality.HighQuality
gphCrop.InterpolationMode = InterpolationMode.High
gphCrop.DrawImage(imgTmp, recDest, 0, 0, imgTmp.Width, imgTmp.Height, GraphicsUnit.Pixel)
Dim myEncoder As System.Drawing.Imaging.Encoder
Dim myEncoderParameter As System.Drawing.Imaging.EncoderParameter
Dim myEncoderParameters As System.Drawing.Imaging.EncoderParameters
Dim arrayICI() As System.Drawing.Imaging.ImageCodecInfo = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()
Dim jpegICI As System.Drawing.Imaging.ImageCodecInfo = Nothing
Dim x As Integer = 0
For x = 0 To arrayICI.Length - 1
If (arrayICI(x).FormatDescription.Equals("JPEG")) Then
jpegICI = arrayICI(x)
Exit For
End If
Next
myEncoder = System.Drawing.Imaging.Encoder.Quality
myEncoderParameters = New System.Drawing.Imaging.EncoderParameters(1)
myEncoderParameter = New System.Drawing.Imaging.EncoderParameter(myEncoder, 60L)
myEncoderParameters.Param(0) = myEncoderParameter
imgFoto.Save(dest, jpegICI, myEncoderParameters)
imgFoto.Dispose()
imgTmp.Dispose()
Catch ex As Exception
End Try
End Function
I want it to save the picture to SQL Server 2008 (Image data type) together with my two data just like this
Using cmd As New SqlClient.SqlCommand("dbo.uspAdd", cn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add("#firstname", SqlDbType.VarChar, 100).Value = txtName.Text
cmd.Parameters.Add("#lastName", SqlDbType.VarChar, 100).Value = txtSurname.Text
'add insert picture code here
cmd.ExecuteNonQuery()
MsgBox("Save Record New record Successfully")
End Using
And now i'm stuck for almost 8 hours finding ways on how to fix this.Can anyone help me to solve this. Any help would be very much appreciated.
I would suggest converting the image to Base64 and then storing it as a string.
Then when you want to get the image back you need to convert it back from Base64 to an image.
You can convert an image to Base64 using this code:
Public Function ConvertImageToBase64(ByRef img As Image, ByVal format As System.Drawing.Imaging.ImageFormat) As String
Dim ImgStream As MemoryStream = New MemoryStream()
img.Save(ImgStream, format)
ImgStream.Close()
Dim ByteArray() As Byte = ImgStream.ToArray()
ImgStream.Dispose()
Return Convert.ToBase64String(ByteArray)
End Function
(http://www.dailycoding.com/posts/convert_image_to_base64_string_and_base64_string_to_image.aspx)
And to convert it back to an image you can use this code:
Public Function ConvertBase64ToImage(ByVal base64 As String) As Image
Dim img As System.Drawing.Image
Dim MS As System.IO.MemoryStream = New System.IO.MemoryStream
Dim b64 As String = base64.Replace(" ", "+")
Dim b() As Byte
b = Convert.FromBase64String(b64)
MS = New System.IO.MemoryStream(b)
img = System.Drawing.Image.FromStream(MS)
Return img
End Function
(http://snipplr.com/view/27514/vbnet-base64-to-image/)
Now you can basically add the image as a string, like this:
Dim Base64Bitmap As String = ConvertImageToBase64(img, System.Drawing.Imaging.ImageFormat.Png)
cmd.Parameters.Add("#Image", SqlDbType.VarChar, Base64Bitmap.Length).Value = Base64Bitmap