[英]How to retrieve image from MySQL database to PictureBox in VB.NET
[英]How to retrieve image from database using ComboBox in VB.NET
我尝试通过它检索图像时遇到有关ComboBox
事件的问题。 因为当我使用这个时:
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim connstring As String = "server = localhost; user id = root; database = db; password = root"
Dim Sql As String = "SELECT * FROM candidate WHERE cid= '" & ComboBox1.SelectedItem & "'"
Dim conn As New MySqlConnection(connstring)
Dim cmd As New MySqlCommand(Sql, conn)
Dim dr As MySqlDataReader = Nothing
conn.Open()
dr = cmd.ExecuteReader()
dr.Read()
If IsDBNull(dr("photo")) = False Then
Dim imagebytes As Byte() = CType(dr("photo"), Byte())
Using ms As New IO.MemoryStream(imagebytes)
PictureBox1.Image = Image.FromStream(ms)
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End Using
End If
conn.Close()
End Sub
发生此错误: Operator '&' is not defined for string "SELECT * FROM candidate WHERE ci" and type 'DataRowView'.
但是如果我使用这个:
Private Sub ComboBox1_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectionChangeCommitted
Dim connstring As String = "server = localhost; user id = root; database = db; password = root"
Dim Sql As String = "SELECT * FROM candidate WHERE cid= '" & ComboBox1.SelectedIndex & "'"
Dim conn As New MySqlConnection(connstring)
Dim cmd As New MySqlCommand(Sql, conn)
Dim dr As MySqlDataReader = Nothing
conn.Open()
dr = cmd.ExecuteReader()
dr.Read()
If IsDBNull(dr("photo")) = False Then
Dim imagebytes As Byte() = CType(dr("photo"), Byte())
Using ms As New IO.MemoryStream(imagebytes)
PictureBox1.Image = Image.FromStream(ms)
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End Using
End If
conn.Close()
End Sub
最初的选择是可行的,但是当我在ComboBox
选择另一个项目时,表单将挂起(无响应)。 我的代码或笔记本电脑有什么问题吗?
这是我填充ComboBox
es的方式:
Private Sub Form4_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
HookKeyboard()
Me.TopMost = True
con.ConnectionString = ("server=localhost;user id=root;database=db;password=root")
Try
con.Open()
With cmd
.Connection = con
.CommandText = "SELECT case when SCQ='0' or cfname='Select a Candidate' then cfname else CONCAT_WS(' ', idn, cfname, cmname, clname,'from', cparty,'party') end names, " & _
"cpos, cid from candidate WHERE cpos='President' AND candidacy='Filed' OR " & _
"cpos='Vice President' AND candidacy='Filed' OR " & _
"cpos='Secretary' OR " & _
"cpos='Treasurer' OR " & _
"cpos='Auditor' OR " & _
"cpos='Public Information Officer' OR " & _
"cpos='Peace Officer' OR " & _
"cpos='Representative (Grade 7)' order by SCQ desc "
End With
Dim dt As New DataTable
da.SelectCommand = cmd
da.Fill(dt)
With ComboBox1
Dim dv = New DataView(dt, "cpos='President'", "", DataViewRowState.CurrentRows)
.DisplayMember = "names"
.ValueMember = "names"
.DataSource = dv
End With
With ComboBox2
Dim dv1 = New DataView(dt, "cpos='Vice President'", "", DataViewRowState.CurrentRows)
.DisplayMember = "names"
.ValueMember = "names"
.DataSource = dv1
End With
With ComboBox3
Dim dv2 = New DataView(dt, "cpos='Secretary'", "", DataViewRowState.CurrentRows)
.DisplayMember = "names"
.ValueMember = "names"
.DataSource = dv2
End With
With ComboBox4
Dim dv3 = New DataView(dt, "cpos='Treasurer'", "", DataViewRowState.CurrentRows)
.DisplayMember = "names"
.ValueMember = "names"
.DataSource = dv3
End With
With ComboBox5
Dim dv4 = New DataView(dt, "cpos='Auditor'", "", DataViewRowState.CurrentRows)
.DisplayMember = "names"
.ValueMember = "names"
.DataSource = dv4
End With
With ComboBox6
Dim dv5 = New DataView(dt, "cpos='Public Information Officer'", "", DataViewRowState.CurrentRows)
.DisplayMember = "names"
.ValueMember = "names"
.DataSource = dv5
End With
With ComboBox7
Dim dv6 = New DataView(dt, "cpos='Peace Officer'", "", DataViewRowState.CurrentRows)
.DisplayMember = "names"
.ValueMember = "names"
.DataSource = dv6
End With
With ComboBox8
Dim dv7 = New DataView(dt, "cpos='Representative (Grade 7)'", "", DataViewRowState.CurrentRows)
.DisplayMember = "names"
.ValueMember = "names"
.DataSource = dv7
End With
Catch ex As Exception
MsgBox(ex.Message)
End Try
con.Close()
End Sub
在大多数情况下,当您不关心各个部分或为用户创建一些新内容时,可以使用CONCAT字段。 例如将concat FirstName和LastName转换为FullName。 实际情况并非如此,您确实想了解一些信息。 可以使用获取每个位置的数据的过程(即,具有7或8个表的数据集-每个位置一个)来简化查询。
Public Class FormX
Private myDS As DataSet ' our data set for the results
Private Form_Load(....
myDS = New DataSet
FillPositionInfo("President")
FillPositionInfo("Vice-President")
...etc
' bind to CBOs:
With ComboBox1
.DisplayMember = "FullName" ' what to show
.ValueMember = "cid" ' value to return to code
.DataSource = myDS.Tables("President")
End With
' add a table to the DS with the candidate info for the requested position
Private Sub FillPositionInfo(position As String)
' maybe CONCAT to create a full name field
Dim sql As String = "SELECT cid, ... FROM Candidate WHERE cpos = @cpos"
' youd use MySql Objects - I only have SQL Server and Access available
Using con As OleDbConnection = GetConnection()
con.Open()
Using cmd As New OleDbCommand(sql, con),
da As New OleDbDataAdapter(sql.Value, con)
cmd.Parameters.AddWithValue("@cpos", position)
da.SelectCommand = cmd
' add a new Tbl named "President" or whatever is requested
myDS.Tables.Add(position)
da.Fill(myDS, position) ' fill the table
' debug - look in the output window
For n As Integer = 0 To myDS.Tables(position).Rows.Count - 1
Console.WriteLine(myDS.Tables(position).Rows(n).Item("cname")
Next
End Using ' dispose cmd and da
con.Close ' return connection to pool
End Using ' dispose con
End Sub
笔记:
我不熟悉您的应用程序和数据库的所有复杂性和详细信息,因此可能需要修复和修改某些内容。 正在说明其中涉及的原理。
由于职位的文字现在至关重要,因此您可能希望使用“常量”或名称数组来防止输入错误。 例如:
Private posTitles As String() = {"President", "Vice President"...}
Private Enum TitleIndex
President = 0
VP = 1
...
End Enum
...
myDS.Tables.Add(posTitles(TitleIndex.VP)) ' add named tbl using array text
CBO.DataSource = myDS.Tables(TitleIndex.VP) ' reference by position
关键是要确保对DS表,CBO,SQL等使用完全相同的文本,而在此处不要使用“ Vice President”,而在别处使用“ Vice-President”。
通过不将所有内容粘合在一起,您的原始问题可能会过时。 如果用于创建表的SQL最少(“ SELECT Fname,LName,CID From ...”),那么您将需要再次点击DB以获取更多信息,例如照片:
' assumes cid is the PK and mapped as the ValueMember
Sql = "SELECT * FROM candidate WHERE cid = '" & ComboBox1.SelectedValue & "'"
(如果cid
是数字,则不需要或不需要滴答声-可能是数据类型转换)。
如果使用“ SELECT *”,则每个DataTable
都将已经包含所有信息,而无需查找任何内容。 所选候选人的字节数组将类似于:
myDS.Tables(X).Rows(Cbo.SelectedIndex).Item("photo")`
您仍然必须将其转换为实际图像,但无需找到它。 有几种方法可以解决此问题-因此,如果您要这样做,则可能需要进行修补。
最后,请注意,这是一个更好的做法是使用SQL参数如图FillPositionInfo
。 字符串格式错误,数据类型不匹配以及免受SQL注入攻击的保护的情况要少得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.