[VB.NET] การนำ ComboBox Control ไปใส่ไว้ในตารางกริด DataGridView แบบ Run Time
http://www.g2gnet.com/webboard/images/vbnet/DataGridComboNet.pngจากตอนที่แล้วแอดมินได้นำเสนอ การนำเอา ComboBox Control ไปใส่ไว้ในตารางกริด MSFlexGrid สำหรับ Visual Basic 6 ในตอนนี้ก็จะขยับมาใช้ VB.NET โดยแบ่งวิธีคิดออกเป็น 3 วิธี ซึ่งแต่ละวิธีจะมีทั้งความเหมือนและความแตกต่างผสมกันไป แอดมินอยากให้ลองศึกษาและสังเกตกันให้ดีๆ เพราะสิ่งที่แอดมินนำมาเล่าสู่กันฟังนี้มันเป็นพื้นฐาน ที่จะนำทางไปสู่การแก้ปัญหาในการเขียนโปรแกรมในลำดับต่อไป ...
3 วิธีคิด แบ่งออกได้ดังต่อไปนี้
- คิดแบบ VB6
- คิดแบบ VB6 แต่ใช้ความสามารถของ VB.NET ในการสร้าง ComboBox แบบ @Run Time
- คิดแบบ Visual Basic .NET ฉบับเต็ม
สำหรับวิธีแรก คงไม่ต้องอธิบายอะไรมากมายนัก ก็คือนำเอา ComboBox มาแปะลงบนฟอร์มก่อน จากนั้นก็อาศัยหลักการเลื่อนตำแหน่ง ComboBox ไปปิดทับในแต่ละเซลล์ที่ต้องการ (ใช้หลักที่ 3 หรือ Index = 2 ตามเดิม)
โค้ดวิธีการแรก
Public Class frmDGVCBV1
Private Sub frmDGVCBV1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
'//
With DataGridView1
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.SelectionMode = DataGridViewSelectionMode.CellSelect
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
.AutoResizeColumns()
.MultiSelect = False
.ColumnCount = 3
.Columns(0).Name = "Column 1"
.Columns(1).Name = "Column 2"
.Columns(2).Name = "Column 3"
'// ป้องกันการเข้าไปแก้ไขในเซลล์โดยตรง
.Columns(2).ReadOnly = True
End With
Dim row As String() = New String() {"1", "Product 1", "M100"}
DataGridView1.Rows.Add(row)
row = New String() {"2", "Product 2", "M100"}
DataGridView1.Rows.Add(row)
row = New String() {"3", "Product 3", "M150"}
DataGridView1.Rows.Add(row)
row = New String() {"4", "Product 4", "M16"}
DataGridView1.Rows.Add(row)
'//
With ComboBox1
.DropDownStyle = 2
'// Load the ComboBox's list.
.Items.Add("M100")
.Items.Add("M150")
.Items.Add("M16")
' Hidden Control
.Visible = False
End With
End Sub
' / -------------------------------------------------------------------------------------
' / เกิดเหตุการณ์การคลิ๊กเซลล์ แถวใดๆแต่เป็นหลักที่ 3 (Index = 2)
Private Sub DataGridView1_CellClick(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellClick
If e.RowIndex < 0 Then Exit Sub
Select Case e.ColumnIndex
'// เราไม่ต้องการหลัก 0 กับหลัก 1 ดังนั้นต้องปิดการแสดงผลของ ComboBox เอาไว้
Case 0 To 1 : ComboBox1.Visible = False
'// โฟกัสมาที่หลักที่ 3 (Index = 2) ที่เราต้องการเท่านั้น
Case 2
'// เปิดให้มองเห็น ComboBox
ComboBox1.Visible = True
'// เพิ่ม ComboBox เข้ามาในตารางกริด
DataGridView1.Controls.Add(ComboBox1)
'// นำค่าจาก DataGrid มาเทียบค่าใน ComboBox เพื่อให้แสดงผลค่าที่เท่ากัน
ComboBox1.Text = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
'// พื้นที่แสดงผลในเซลล์.
Dim oRectangle = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True)
' หาค่าระยะ X, Y เพื่อกำหนดพิกัด (Coordinate) ให้กับ ComboBox
ComboBox1.Size = New Size(oRectangle.Width, oRectangle.Height)
'// กำหนดตำแหน่งของ ComboBox ไปทับเซลล์
ComboBox1.Location = New Point(oRectangle.X, oRectangle.Y)
End Select
End Sub
' / -------------------------------------------------------------------------------------
' / หากเกิดการเลือกค่าใน ComboBox ก็ให้คัดลอกค่านี้ไปยังเซลล์ใน DataGridView
Private Sub ComboBox1_TextChanged(sender As Object, e As System.EventArgs) Handles ComboBox1.TextChanged
'// นำค่าจาก ComboBox ไปใส่ไว้ในเซลล์ของ DataGridView
DataGridView1.CurrentCell.Value = ComboBox1.Text
End Sub
Private Sub frmDGVCBV1_Resize(sender As Object, e As System.EventArgs) Handles Me.Resize
ComboBox1.Visible = False
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
'// นำค่าจาก ComboBox ไปใส่ไว้ในเซลล์ของ DataGridView
DataGridView1.CurrentCell.Value = ComboBox1.Text
End Sub
Private Sub frmDGVCBV1_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
Me.Dispose()
End Sub
End Class
วิธีการที่สอง ก็จะใช้เหมือนวิธีการแรก แต่เปลี่ยนใหม่โดยให้สร้าง ComboBox Control ขึ้นมาในขณะ @Run Time แทน
'// ประกาศตัวแปร Object ของ ComboBox
Dim cb As New ComboBoxประกาศตัวแปร ComboBox
'// Declare columns type.
Dim Column1 As New DataGridViewTextBoxColumn()
Dim Column2 As New DataGridViewTextBoxColumn()
Dim Column3 As New DataGridViewTextBoxColumn()
'// Add new Columns
DataGridView1.Columns.AddRange(New DataGridViewColumn() { _
Column1, Column2, Column3 _
})
With DataGridView1
.Columns(0).Name = "Column 1"
.Columns(1).Name = "Column 2"
.Columns(2).Name = "Column 3"
'// ป้องกันการเข้าไปแก้ไขในเซลล์โดยตรง
.Columns(2).ReadOnly = True
End With
'//
With cb
.DropDownStyle = 2
'// Load the ComboBox's list.
.Items.Add("M100")
.Items.Add("M150")
.Items.Add("M16")
'// Hidden Control
.Visible = False
End Withให้สังเกตดูว่าในหลักที่ 3 (Index = 2) แอดมินยังกำหนดช่องเซลล์ DataGridViewTextBoxColumn คือยังคงเป็นแบบ TextBox ตามเดิม
' / -------------------------------------------------------------------------------------
' / เกิดเหตุการณ์การคลิ๊กเซลล์ แถวใดๆแต่เป็นหลักที่ 3 (Index = 2)
Private Sub DataGridView1_CellClick(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellClick
If e.RowIndex < 0 Then Exit Sub
Select Case e.ColumnIndex
'// เราไม่ต้องการหลัก 0 กับหลัก 1 ดังนั้นต้องปิดการแสดงผลของ ComboBox เอาไว้
Case 0 To 1 : cb.Visible = False
'// โฟกัสมาที่หลักที่ 3 (Index = 2) ที่เราต้องการเท่านั้น
Case 2
'// เปิดให้มองเห็น ComboBox
cb.Visible = True
'// Adding ComboBox control into DataGridView
DataGridView1.Controls.Add(cb)
'// นำค่าจาก DataGrid มาเทียบค่าใน ComboBox เพื่อให้แสดงผลค่าที่เท่ากัน
cb.Text = DataGridView1.CurrentCell.Value
'// พื้นที่แสดงผลในเซลล์.
Dim oRectangle = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True)
' หาค่าระยะ X, Y เพื่อกำหนดพิกัด (Coordinate) ให้กับ ComboBox
cb.Size = New Size(oRectangle.Width, oRectangle.Height)
'// Setting Location
cb.Location = New Point(oRectangle.X, oRectangle.Y)
'// การสร้างเหตุการณ์ (Event) เมื่อเกิดการเลือกไอเทมใน ComboBox ก็จะส่งผลให้กับเซลล์ในตารางกริด
AddHandler cb.TextChanged, AddressOf cb_TextChanged
End Select
End Sub
' / -------------------------------------------------------------------------------------
' / หากเกิดการเลือกค่าใน ComboBox ก็ให้คัดลอกค่านี้ไปยังเซลล์ใน DataGridView
Private Sub cb_TextChanged(sender As Object, e As System.EventArgs)
cb.Visible = False
'// นำค่าจาก ComboBox ไปใส่ไว้ในเซลล์ของ DataGridView
If DataGridView1.CurrentCell.ColumnIndex = 2 AndAlso cb.Text <> "" Then DataGridView1.CurrentCell.Value = cb.Text
End Subนอกเหนือไปจากการคำนวณหาตำแหน่งที่ ComboBox จะต้องเคลื่อนย้ายไปปิดทับเซลล์แล้ว เราจะต้องสร้างเหตุการณ์ (Event) เมื่อเกิดการเลือกค่าไอเทมใน ComboBox เพิ่มขึ้นมาอีก (AddHandler cb.TextChanged, AddressOf cb_TextChanged) ในส่วนนี้เองที่ VB.NET ได้เพิ่มขีดความสามารถขึ้นมาสูงกว่า VB6
โค้ดวิธีการที่สอง
Public Class frmDGVCBV2
'// ประกาศตัวแปร Object ของ ComboBox
Dim cb As New ComboBox
Private Sub frmDGVCBV2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
'//
With DataGridView1
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.SelectionMode = DataGridViewSelectionMode.CellSelect
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
.AutoResizeColumns()
.MultiSelect = False
End With
'// Declare columns type.
Dim Column1 As New DataGridViewTextBoxColumn()
Dim Column2 As New DataGridViewTextBoxColumn()
Dim Column3 As New DataGridViewTextBoxColumn()
'// Add new Columns
DataGridView1.Columns.AddRange(New DataGridViewColumn() { _
Column1, Column2, Column3 _
})
With DataGridView1
.Columns(0).Name = "Column 1"
.Columns(1).Name = "Column 2"
.Columns(2).Name = "Column 3"
'// ป้องกันการเข้าไปแก้ไขในเซลล์โดยตรง
.Columns(2).ReadOnly = True
End With
'//
With cb
.DropDownStyle = 2
'// Load the ComboBox's list.
.Items.Add("M100")
.Items.Add("M150")
.Items.Add("M16")
'// Hidden Control
.Visible = False
End With
'//
Dim row As String() = New String() {"1", "Product 1", "M100"}
DataGridView1.Rows.Add(row)
row = New String() {"2", "Product 2", "M100"}
DataGridView1.Rows.Add(row)
row = New String() {"3", "Product 3", "M150"}
DataGridView1.Rows.Add(row)
row = New String() {"4", "Product 4", "M16"}
DataGridView1.Rows.Add(row)
End Sub
' / -------------------------------------------------------------------------------------
' / เกิดเหตุการณ์การคลิ๊กเซลล์ แถวใดๆแต่เป็นหลักที่ 3 (Index = 2)
Private Sub DataGridView1_CellClick(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellClick
If e.RowIndex < 0 Then Exit Sub
Select Case e.ColumnIndex
'// เราไม่ต้องการหลัก 0 กับหลัก 1 ดังนั้นต้องปิดการแสดงผลของ ComboBox เอาไว้
Case 0 To 1 : cb.Visible = False
'// โฟกัสมาที่หลักที่ 3 (Index = 2) ที่เราต้องการเท่านั้น
Case 2
'// เปิดให้มองเห็น ComboBox
cb.Visible = True
'// Adding ComboBox control into DataGridView
DataGridView1.Controls.Add(cb)
'// นำค่าจาก DataGrid มาเทียบค่าใน ComboBox เพื่อให้แสดงผลค่าที่เท่ากัน
cb.Text = DataGridView1.CurrentCell.Value
'// พื้นที่แสดงผลในเซลล์.
Dim oRectangle = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True)
' หาค่าระยะ X, Y เพื่อกำหนดพิกัด (Coordinate) ให้กับ ComboBox
cb.Size = New Size(oRectangle.Width, oRectangle.Height)
'// Setting Location
cb.Location = New Point(oRectangle.X, oRectangle.Y)
'// การสร้างเหตุการณ์ (Event) เมื่อเกิดการเลือกไอเทมใน ComboBox ก็จะส่งผลให้กับเซลล์ในตารางกริด
AddHandler cb.TextChanged, AddressOf cb_TextChanged
End Select
End Sub
' / -------------------------------------------------------------------------------------
' / หากเกิดการเลือกค่าใน ComboBox ก็ให้คัดลอกค่านี้ไปยังเซลล์ใน DataGridView
Private Sub cb_TextChanged(sender As Object, e As System.EventArgs)
cb.Visible = False
'// นำค่าจาก ComboBox ไปใส่ไว้ในเซลล์ของ DataGridView
If DataGridView1.CurrentCell.ColumnIndex = 2 AndAlso cb.Text <> "" Then DataGridView1.CurrentCell.Value = cb.Text
End Sub
' / -------------------------------------------------------------------------------------
' / หากเกิดการเลือกค่าใน ComboBox ก็ให้คัดลอกค่านี้ไปยังเซลล์ใน DataGridView
Private Sub DataGridView1_CellLeave(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellLeave
cb.Visible = False
If DataGridView1.CurrentCell.ColumnIndex = 2 AndAlso cb.Text <> "" Then DataGridView1.CurrentCell.Value = cb.Text
End Sub
Private Sub frmDGVCBV2_Resize(sender As Object, e As System.EventArgs) Handles Me.Resize
cb.Visible = False
End Sub
Private Sub frmDGVCBV2_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
Me.Dispose()
End Sub
End Class
สำหรับวิธีการที่สาม เราๆท่านๆก็คงจะพบเห็นข้อมูลได้ทั่วๆไปตามเว็บไซต์ต่างๆนั่นเอง โดยอาศัยขีดความสามารถที่มีอยู่ในตัวของ VB.NET ในการเพิ่ม Control ในตัวของ DataGridView ...
'// เพิ่ม ComboBox
Dim cmb As New DataGridViewComboBoxColumn()
With cmb
.HeaderText = "ComboBox"
.Items.Add("M100")
.Items.Add("M150")
.Items.Add("M16")
End With
DataGridView1.Columns.Add(cmb)ก็เพราะ DataGridView มันมีกลวิธี (Method) ในการนำเอา ComboBox มาใส่ไว้ในเซลล์ของตัวมันเองได้นั่นเอง
โค้ดวิธีการที่สาม
Public Class frmDGVCBV3
Private Sub frmDGVCBV3_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
'//
With DataGridView1
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.SelectionMode = DataGridViewSelectionMode.CellSelect
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
.AutoResizeColumns()
.MultiSelect = False
End With
'// Declare columns type.
Dim Column1 As New DataGridViewTextBoxColumn()
Dim Column2 As New DataGridViewTextBoxColumn()
'// Add new Columns
DataGridView1.Columns.AddRange(New DataGridViewColumn() { _
Column1, Column2 _
})
With DataGridView1
.Columns(0).Name = "Column 1"
.Columns(1).Name = "Column 2"
End With
'// เพิ่ม ComboBox
Dim cmb As New DataGridViewComboBoxColumn()
With cmb
.HeaderText = "ComboBox"
.Items.Add("M100")
.Items.Add("M150")
.Items.Add("M16")
End With
DataGridView1.Columns.Add(cmb)
'//
Dim row As String() = New String() {"1", "Product 1", "M100"}
DataGridView1.Rows.Add(row)
row = New String() {"2", "Product 2", "M100"}
DataGridView1.Rows.Add(row)
row = New String() {"3", "Product 3", "M150"}
DataGridView1.Rows.Add(row)
row = New String() {"4", "Product 4", "M16"}
DataGridView1.Rows.Add(row)
'//
End Sub
Private Sub frmDGVCBV3_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
Me.Dispose()
End Sub
End Class
Conclusion: หลายๆคนอาจจะงงและสงสัยว่า ทำไมแอดมินต้องมาใช้วิธีการอะไรให้ยุ่งยาก ก็เล่นแบบวิธีการที่ 3 ไปเลยซ่ะก็สิ้นเรื่อง ... ลองคิดเล่นๆดูก่อนว่าหากเราต้องการเพิ่ม DateTimePicker (หรือ Control ตัวอื่นๆ) เข้าไปในเซลล์ของตารางกริดแทน ComboBox ท่านจะทำอย่างไร???
ดาวนโหลดโค้ดต้นฉบับ VB.NET (2010) ได้ที่นี่
มีตัวอย่างแบบทำเป็นChedkbox ไหมครับ komenservice ตอบกลับเมื่อ 2020-7-14 11:26
มีตัวอย่างแบบทำเป็นChedkbox ไหมครับ
Dim chk As New DataGridViewCheckBoxColumn()
chk.HeaderText = "Check Box"
DataGridView1.Columns.Add(chk)
'//
Dim row As String() = New String() {"1", "Product 1", "M100", True}
DataGridView1.Rows.Add(row)
row = New String() {"2", "Product 2", "M100", False}
DataGridView1.Rows.Add(row)
row = New String() {"3", "Product 3", "M150", False}
DataGridView1.Rows.Add(row)
row = New String() {"4", "Product 4", "M16", True}
DataGridView1.Rows.Add(row) ขอบคุณครับ
หน้า:
[1]