使用列表框从 SQL 获取图像到图片框 VB

Get Image from SQL using Listbox to picturebox VB

我正在尝试使用 VB 中的列表框将图像从 SQL 获取到图片框。

这是我的 sql 示例 table。

这是我的 VB 设计表单,所以我想做的是当我加载表单时,如果选择了列表框中的项目,我希望它获取图像(二进制数据)从 sql 到 vb net.

中的图片框

我正在使用它的代码给了我这个错误:

VB完整代码:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    connect()
    Dim co As New SqlConnection("Data Source=WXCQSDQSD\SQLEXPRESS;Initial Catalog=food;Integrated Security = True")
    co.Open()
    Dim com As New SqlCommand("SELECT Image from Items where ItemName = '" & ListBox1.SelectedIndex & "'", co)
    Dim img As Byte() = DirectCast(com.ExecuteScalar(), Byte())
    Dim ms As MemoryStream = New MemoryStream(img)

    Dim dt = GetDataFromSql()
    Dim BndSrc As New BindingSource()
    BndSrc.DataSource = dt
    ListBox1.DisplayMember = "ItemName"
    ListBox1.DataSource = BndSrc
    TextBox1.DataBindings.Add("Text", BndSrc, "ItemID")
    TextBox2.DataBindings.Add("Text", BndSrc, "ItemName")
    TextBox3.DataBindings.Add("Text", BndSrc, "Details")
    PictureBox1.Image = Image.FromStream(ms)

End Sub
Private Function GetDataFromSql() As DataTable
    Dim dt As New DataTable
    Using connection As New SqlConnection("Data Source=WXCQSDQSD\SQLEXPRESS;Initial Catalog=food;Integrated Security = True"),
            cmd As New SqlCommand("select * FROM Items", connection)
        connection.Open()
        Using reader = cmd.ExecuteReader
            dt.Load(reader)
        End Using
    End Using
    Return dt
End Function

进口System.Data.SqlClient 进口 System.IO Public Class Form1

Dim con As SqlConnection
Dim cmd As SqlCommand
Dim rdr As SqlDataReader
Dim da As SqlDataAdapter
Private Const cs As String = "ConnectionString"

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    con = New SqlConnection(cs)
    con.Open()
    cmd = New SqlCommand("select * from [dbo].[Item_Details]", con)
    rdr = cmd.ExecuteReader()
    While rdr.Read
        ListBox1.Items.Add(rdr(1))
    End While
    con.Close()
End Sub

Private Sub ListBox1_MouseClick(sender As Object, e As MouseEventArgs) Handles ListBox1.MouseClick
    Try

        con = New SqlConnection(cs)
        con.Open()
        da = New SqlDataAdapter("Select *  from Item_Details where itemname='" & ListBox1.SelectedItem.ToString() & "'", con)
        Dim dt As New DataTable
        da.Fill(dt)
        For Each row As DataRow In dt.Rows
            TextBox1.Text = row(0).ToString()
            TextBox2.Text = row(1).ToString()
            TextBox3.Text = row(2).ToString()
            Dim data As Byte() = row(3)
            Dim ms As New MemoryStream(data)
            PictureBox1.Image = Image.FromStream(ms)
        Next

    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub

结束Class

Form.Load中删除图片检索。我们在GetDataFromSql函数中选择了所有的数据。魔术发生在 ListBox1.SelectedIndexChanged 方法中。

SelectedIndexChanged 将作为 Form.Load 中代码的结果以及每次选择更改时发生。当我们将列表框绑定到绑定源时,整行添加为 DataRowView。我们可以使用它来获取 Image 列中的数据。首先检查该字段是否为空。接下来转换为字节数组。获取字节数组并将其传递给 MemoryStream 的构造函数。需要处理流,因此它位于 Using 块中。最后可以将流分配给PictureBox.

Image属性
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim dt = GetDataFromSql()
    Dim BndSrc As New BindingSource()
    BndSrc.DataSource = dt
    ListBox1.DisplayMember = "ItemName"
    ListBox1.DataSource = BndSrc
    TextBox1.DataBindings.Add("Text", BndSrc, "ItemID")
    TextBox2.DataBindings.Add("Text", BndSrc, "ItemName")
    TextBox3.DataBindings.Add("Text", BndSrc, "Details")
End Sub

Private Function GetDataFromSql() As DataTable
    Dim dt As New DataTable
    Using connection As New SqlConnection("Data Source=WXCQSDQSD\SQLEXPRESS;Initial Catalog=food;Integrated Security = True"),
        cmd As New SqlCommand("select * FROM Items", connection)
        connection.Open()
        Using reader = cmd.ExecuteReader
            dt.Load(reader)
        End Using
    End Using
    Return dt
End Function

Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
    Dim row = DirectCast(ListBox1.SelectedItem, DataRowView)
    If row("Image") IsNot Nothing Then
        Dim b() As Byte = DirectCast(row("Image"), Byte()) '< ------ Cast the field to a Byte array.
        Using ms As New System.IO.MemoryStream(b)
            PictureBox1.Image = System.Drawing.Image.FromStream(ms)
        End Using
    Else
        PictureBox1.Image = Nothing
    End If
End Sub

编辑

我将代码切换到可用于测试的数据库。尽管它不是您的数据库,但我相信您将能够遵循代码。

这是我的数据库的架构。

主要区别是我将 DataTable 移动到 class 级别变量,因此可以从所有方法中看到它。我将 GetDataFromSql 更改为 Sub。它将数据添加到 class 级别 DataTable (Bounddt)。 AddItem 方法首先从文件中获取 Byte()。该行被添加到 DataTable 中,带有一个 Object 数组,其中的元素与 DataTable 匹配。

Private Bounddt As New DataTable

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    GetDataFromSql()
    Dim BndSrc As New BindingSource()
    BndSrc.DataSource = Bounddt
    ListBox1.DisplayMember = "CustomerID"
    ListBox1.DataSource = BndSrc
    TextBox1.DataBindings.Add("Text", BndSrc, "CustomerID")
    TextBox2.DataBindings.Add("Text", BndSrc, "CustomerName")
End Sub

Private Sub GetDataFromSql() 
    Using connection As New SqlConnection("Data Source=****;Initial Catalog='Small Database';Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"),
    cmd As New SqlCommand("select * FROM Sales.Customer", connection)
        connection.Open()
        Using reader = cmd.ExecuteReader
            Bounddt.Load(reader)
        End Using
    End Using
    'Return dt
End Sub

Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
    Dim row = DirectCast(ListBox1.SelectedItem, DataRowView)
    If row("Picture") IsNot Nothing Then
        Dim b() As Byte = DirectCast(row("Picture"), Byte()) '< ------ Cast the field to a Byte array.
        Using ms As New System.IO.MemoryStream(b)
            PictureBox1.Image = System.Drawing.Image.FromStream(ms)
        End Using
    Else
        PictureBox1.Image = Nothing
    End If
End Sub
Private Sub AddItem()
    Dim picture = GetByteArr("C:\Users\maryo\OneDrive\Documents\Graphics\Animals\squirrel.png")
    Bounddt.Rows.Add({5, "George", 74, 62, "George", picture})
End Sub

Private Function GetByteArr(path As String) As Byte()
    Dim img = Image.FromFile(path)
    Dim arr As Byte()
    Dim imgFor As Imaging.ImageFormat
    Dim extension = path.Substring(path.LastIndexOf(".") + 1)
    'There is a longer list of formats available in ImageFormat
    Select Case extension
        Case "png"
            imgFor = Imaging.ImageFormat.Png
        Case "jpg", "jpeg"
            imgFor = Imaging.ImageFormat.Jpeg
        Case "bmp"
            imgFor = Imaging.ImageFormat.Bmp
        Case Else
            MessageBox.Show("Not a valid image format")
            Return Nothing
    End Select
    Using ms As New MemoryStream
        img.Save(ms, imgFor)
        arr = ms.ToArray
    End Using
    Return arr
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    AddItem()
End Sub