#vb.net
Вопрос:
я пытаюсь перенести изображение из SQL в picturebox, используя Listbox в VB.
вот моя таблица примеров sql.
и вот моя форма дизайна VB, поэтому я пытаюсь сделать следующее: когда я загружаю форму, если выбран элемент в списке, я хочу, чтобы он получал изображение(двоичные данные) из sql в picturebox в vb net.
и код, с которым я работаю, выдает мне эту ошибку:
VB полный код:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
connect()
Dim co As New SqlConnection("Data Source=WXCQSDQSDSQLEXPRESS;Initial Catalog=food;Integrated Security = True")
co.Open()
Dim com As New SqlCommand("SELECT Image from Items where ItemName = '" amp; ListBox1.SelectedIndex amp; "'", 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=WXCQSDQSDSQLEXPRESS;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
Комментарии:
1. Ваш
Form1_Load
метод неправильно распоряжается ресурсами подключения к БД.2. Используйте a и его метод для чтения / записи.
SqlDataReader
GetSqlBinary()
binary
varbinary
Вам не следует использовать устаревшийimage
тип данных столбца.
Ответ №1:
Удалите поиск изображений из Form.Load
. Мы выбрали все данные в GetDataFromSql
функции. Волшебство происходит в ListBox1.SelectedIndexChanged
методе.
Это SelectedIndexChanged
будет происходить в результате кода в Form.Load
и каждый раз, когда выбор меняется. Когда мы привязываем поле списка к источнику привязки, вся строка добавляется как a DataRowView
. Мы можем использовать это для получения данных в столбце Изображение. Сначала проверьте, является ли поле пустым. Затем приведите к массиву байтов. Возьмите массив байтов и передайте его конструктору a MemoryStream
. Потоки должны быть расположены так, чтобы они находились в Using
блоке. Наконец, поток может быть присвоен Image
свойству PictureBox
.
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=WXCQSDQSDSQLEXPRESS;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
на уровень класса, чтобы ее можно было увидеть из всех методов. Я сменил GetDataFromSql
Sub
его на «а». Он добавляет данные на уровень класса DataTable
( Bounddt
). AddItem
Метод сначала получает Byte()
данные из файла. Строка добавляется в DataTable
массив Object
с элементами, соответствующими таблице данных.
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:UsersmaryoOneDriveDocumentsGraphicsAnimalssquirrel.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
Комментарии:
1. у меня есть небольшая проблема: всякий раз, когда я выполняю или добавляю другой элемент в поле списка, поле списка не обновляет элементы, если я снова не перезапущу форму. Я попытался дублировать событие form_load и selectedindex в кнопке, поэтому всякий раз, когда я нажимаю кнопку, она снова запускает код, но, похоже, это не работает.
2. @PotatoPythonLearner Я должен был попросить вас задать новый вопрос, но я просто добавил ответ в качестве правки.
3. это здорово! большое вам спасибо!
Ответ №2:
Импортирует систему.Данные.SqlClient Импортирует Систему.IO Форма публичного Класса1
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='" amp; ListBox1.SelectedItem.ToString() amp; "'", 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
Конечный класс
Комментарии:
1. @ученик картофельного питона Этот код будет вам полезен
2. я не знаю. похоже, что изображение из поля sql в поле изображения выбранного элемента в списке не отображается
3. Привет @Ученик картофельного питона Ты пробовал с этим кодом? Это работает так, как вы ожидаете.