[VB.NET] การนำไฟล์ข้อมูลภาพมาแสดงผลในเซลล์ของตารางกริดแบบ Run Time
http://www.g2gnet.com/webboard/images/vbnet/datagridcolumnimage.pngจากโปรเจค แจกฟรีโค้ดโปรแกรมการเก็บบันทึกข้อมูลบุคคล แอดมินจะขอเลือกส่วนสำคัญเพื่อนำมาอธิบายรายละเอียดกันนะครับ สำหรับบทความนี้ คือ การนำไฟล์ข้อมูลภาพมาแสดงผลในเซลล์ของตารางกริดแบบ Run Time ก็เพราะเนื่องจากว่าในฐานข้อมูล MS Access ที่แอดมินออกแบบเอาไว้ จะบันทึกเฉพาะชื่อไฟล์ (PictureName) เอาไว้เท่านั้น ไม่ได้จัดเก็บข้อมูลในรูปแบบ BLOB (Binary Large OBject) ซึ่งจะทำให้ฐานข้อมูลไม่ใหญ่โตเทอะทะ อีกทั้งมีข้อดีที่สำคัญมากคือ สามารถย้ายระบบไปใช้ฐานข้อมูลค่ายอื่นๆได้อย่างไม่ยากเย็นอะไร ...
การที่จะทำเช่นนี้ได้ต้องอาศัยวิธีการที่เราเรียกว่า UnBound Data Control หรือ การไม่ผูกข้อมูลใดๆเข้ากับคอนโทรล เพื่อที่จะสามารถนำชื่อไฟล์ภาพจากตารางข้อมูล ให้ไปปรากฏอยู่ในเซลล์ของตารางกริดได้ (พื้นฐานการนำข้อมูลจาก DataBase มาแสดงผลบนตารางกริด (Data Reader))
http://www.g2gnet.com/webboard/images/vbnet/datagridcolumnimagedb.png
หากไม่มีข้อมูลภาพ เราก็ให้เป็นค่าว่าง (Blank) เอาไว้
โค้ดในส่วนของการนำข้อมูลมาแสดงผล ...
' / --------------------------------------------------------------------------------
' / Collect all searches and impressions. Come in the same place
' / blnSearch = True, Show that the search results.
' / blnSearch is set to False, Show all records.
Private Sub RetrieveData(Optional ByVal blnSearch As Boolean = False)
strSQL = _
" SELECT tblContact.ContactPK, tblContact.Fullname, tblContact.Nickname, tblContact.Mobile, " & _
" tblContact.Phone, tblContact.eMail, tblContact.LineID, tblContact.FacebookID, " & _
" tblContact.PictureName, tblContact.Note, " & _
" tblPosition.PositionName, tblDepartment.DepartmentName " & _
" FROM INNER JOIN (tblDepartment INNER JOIN tblContact ON " & _
" tblDepartment.DepartmentPK = tblContact.DepartmentFK) ON tblPosition.PositionPK = tblContact.PositionFK "
'// blnSearch = True for Serach
If blnSearch Then
strSQL = strSQL & _
" WHERE " & _
" " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" " & " Like '%" & txtSearch.Text & "%'" & _
" ORDER BY ContactPK "
Else
strSQL = strSQL & " ORDER BY ContactPK "
End If
'//
Try
Cmd = New OleDbCommand
If Conn.State = ConnectionState.Closed Then Conn.Open()
Cmd.Connection = Conn
Cmd.CommandText = strSQL
Dim DR As OleDbDataReader = Cmd.ExecuteReader
Dim i As Long = dgvData.RowCount
While DR.Read
With dgvData
.Rows.Add(i)
.Rows(i).Cells(0).Value = DR.Item("ContactPK").ToString
.Rows(i).Cells(1).Value = DR.Item("Fullname").ToString
.Rows(i).Cells(2).Value = DR.Item("Nickname").ToString
.Rows(i).Cells(3).Value = DR.Item("PositionName").ToString
.Rows(i).Cells(4).Value = DR.Item("DepartmentName").ToString
.Rows(i).Cells(5).Value = DR.Item("Mobile").ToString
.Rows(i).Cells(6).Value = DR.Item("Phone").ToString
.Rows(i).Cells(7).Value = DR.Item("eMail").ToString
.Rows(i).Cells(8).Value = DR.Item("LineID").ToString
.Rows(i).Cells(9).Value = DR.Item("FaceBookID").ToString
'// Show picture in cell.
If DR.Item("PictureName").ToString <> "" Then
'//dgvData.Rows(i).Height = 75
'// Column 10 = "PictureName"
dgvData.Columns(10).Width = 75
'// First, before load data into DataGrid and check File exists or not?
If Dir(strPathImages & DR.Item("PictureName").ToString) = "" Then
'// strPathImages in modDataBase.vb
dgvData.Rows(i).Cells(10).Value = Image.FromFile(strPathImages & "people.png")
Else
dgvData.Rows(i).Cells(10).Value = Image.FromFile(strPathImages & DR.Item("PictureName").ToString)
End If
'// If image is not exists, then show default image.
Else
dgvData.Rows(i).Cells(10).Value = Image.FromFile(strPathImages & "people.png")
'//dgvData.Rows(i).Height = 75
dgvData.Columns(10).Width = 75
End If
' / --------------------------------------------------------------------------------
'// Keep picture's name into TAG for each cell in DataGrid.
'// Used to load images into PictureBox or apply for something else.
dgvData.Rows(i).Cells(10).Tag = DR.Item("PictureName").ToString
' / --------------------------------------------------------------------------------
'//
.Rows(i).Cells(11).Value = DR.Item("Note").ToString
End With
i += 1
End While
lblRecordCount.Text = ""
DR.Close()
'// Adjust row height.
If chkPicture.Checked Then
dgvData.Columns("PictureName").Visible = True
'// Jump to sub program
Call AdjustRowHeight(75)
Else
dgvData.Columns("PictureName").Visible = False
Call AdjustRowHeight(28)
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
'//
txtSearch.Clear()
End Sub
ต้องทำการตรวจสอบก่อนว่ามีชื่อไฟล์ภาพอยู่หรือไม่ หากไม่มีให้โหลดภาพอื่น (people.png) ลงไปแทน ไม่อย่างนั้นมันก็จะเกิดเอ้อเหรอซิครับ
'// First, before load data into DataGrid and check File exists or not?
If Dir(strPathImages & DR.Item("PictureName").ToString) = "" Then
'// strPathImages in modDataBase.vb
dgvData.Rows(i).Cells(10).Value = Image.FromFile(strPathImages & "people.png")
Else
dgvData.Rows(i).Cells(10).Value = Image.FromFile(strPathImages & DR.Item("PictureName").ToString)
End Ifเพราะเนื่องจากหลักที่ 10 (เป็นค่า Index นะครับ) เรากำหนดให้เป็น Dim colPicture As New DataGridViewImageColumn มันถึงจะแสดงผลภาพออกมา ... แล้วถ้าหากว่าต้องการอยากรู้ชื่อไฟล์ภาพแต่ละภาพจะทำอย่างไร???
จะมีอยู่บรรทัดคำสั่งหนึ่ง คือการโหลดชื่อไฟล์ภาพเข้าสู่คุณสมบัติ TAG ในเซลล์ของตารางกริด คือ ...
' / --------------------------------------------------------------------------------
'// Keep picture's name into TAG for each cell in DataGrid.
'// Used to load images into PictureBox or apply for something else.
dgvData.Rows(i).Cells(10).Tag = DR.Item("PictureName").ToString
' / --------------------------------------------------------------------------------นั่นก็หมายความว่า หากเราต้องการนำชื่อไฟล์ภาพไปใช้งานก็กำหนดที่นี่แหละครับ ทำให้เราประหยัดตัวแปร หรือไม่ต้องเพิ่มหลักของตารางกริดเพื่อเอาข้อมูลมาซ่อน ... นี่ก็เป็นอีกหนึ่งเคล็ดลับเทคนิคของการใช้งานตารางกริด
การหาค่า Primary Key และเรียกใช้ชื่อไฟล์ภาพ ... จะอยู่ในเหตุการณ์ของการดับเบิ้ลคลิ๊กเมาส์ในแต่ละแถวของตารางกริด
http://www.g2gnet.com/webboard/images/vbnet/datagridcolumnimagepk.png
' / -----------------------------------------------------------------------------
' / Double Click mouse on DataGridView.
' / -----------------------------------------------------------------------------
Private Sub dgvData_DoubleClick(sender As Object, e As System.EventArgs) Handles dgvData.DoubleClick
If dgvData.RowCount <= 0 Then Return
'// Read the value of the focus row.
Dim iRow As Integer = dgvData.CurrentRow.Index
'// Get Primary Key in Column(0) and show picture's name which It is stored in TAG property each cell.
MessageBox.Show("Primary Key is : " & dgvData.Item(0, iRow).Value & vbCrLf & _
"Picture Name: " & dgvData.Item(10, iRow).Tag)
End Sub
กรณีที่เราต้องการให้แสดงหรือไม่แสดงผลรูปภาพ ...
' / -----------------------------------------------------------------------------
' / Show picture or not?
' / -----------------------------------------------------------------------------
Private Sub chkPicture_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles chkPicture.CheckedChanged
If chkPicture.Checked Then
dgvData.Columns("PictureName").Visible = True
Call AdjustRowHeight(75)
Else
dgvData.Columns("PictureName").Visible = False
Call AdjustRowHeight(28)
End If
End Sub
' / -----------------------------------------------------------------------------
' / Change the height of the rows.
' / -----------------------------------------------------------------------------
Private Sub AdjustRowHeight(h As Integer)
For i As Integer = 0 To dgvData.Rows.Count - 1
dgvData.Rows(i).Height = h
Next
End Subมันจำเป็นจะต้องมีการปรับขนาดความสูงของแถวแบบ @Run Time ตามโค้ดด้านบน ในกรณีที่ปิดเปิดการแสดงผลภาพ
แถมท้าย ... การออกแบบตารางกริด แอดมินชอบการใช้โค้ดสั่งให้ทำงานในขณะ Run Time (โปรแกรมทำงานจึงจะเห็นผล) มากกว่า Design Time (ปรับแต่งคุณสมบัติต่างๆก่อนทำการสั่งรัน) ก็เพราะมีหลายๆเหตุผล หลักๆก็คือหากเราต้องการเพิ่มฟิลด์ (Field ไม่ได้อ่านว่า ฟิว) หรือตัดออกในภายหลัง สามารถทำได้ง่ายและรวดเร็วกว่า หรือการโยกย้ายไปใช้ Control ของค่ายอื่นๆแทนก็ง่ายดาย ดังนั้นแอดมินขอแนะนำให้เขียนโค้ดทำเป็นเทมเพลตเอาไว้รอล่วงหน้าเลยครับ
' / --------------------------------------------------------------------------------
'// Initialize DataGridView @Run Time
Private Sub SetupDGVData()
With dgvData
.RowHeadersVisible = False
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.AllowUserToResizeRows = False
.MultiSelect = False
.SelectionMode = DataGridViewSelectionMode.FullRowSelect
.ReadOnly = True
.Font = New Font("Tahoma", 9)
' Columns Specified
.Columns.Add("ContactPK", "ContactPK")
.Columns.Add("Fullname", "Full name")
.Columns.Add("Nickname", "Nickname")
.Columns.Add("PositionName", "Position")
.Columns.Add("DepartmentName", "Department")
.Columns.Add("Mobile", "Mobile")
.Columns.Add("Phone", "Phone Ext.")
.Columns.Add("Email", "Email")
.Columns.Add("LineID", "Line")
.Columns.Add("FacebookID", "Facebook")
'// Column Picture
Dim colPicture As New DataGridViewImageColumn
.Columns.Add(colPicture)
With colPicture
.HeaderText = "Picture"
.Name = "PictureName"
.ImageLayout = DataGridViewImageCellLayout.Stretch
End With
'//
.Columns.Add("Note", "Note")
'// Hidden Columns
.Columns(0).Visible = False
.Columns(7).Visible = False
.Columns(8).Visible = False
.Columns(9).Visible = False
'// PictureName
.Columns("PictureName").Visible = True
.Columns("Note").Visible = False
' Autosize Column
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
.AutoResizeColumns()
'// Even-Odd Color
.AlternatingRowsDefaultCellStyle.BackColor = Color.AliceBlue
' Adjust Header Styles
With .ColumnHeadersDefaultCellStyle
.BackColor = Color.Navy
.ForeColor = Color.Black ' Color.White
.Font = New Font("Tahoma", 9, FontStyle.Bold)
End With
End With
End Subสำหรับตอนนี้ก็ขอจบแต่เพียงเท่านี้ ... สวัสดี
ดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) ได้ที่นี่
ขอบคุณครับ
หน้า:
[1]