|
จากตอนที่แล้วแอดมินได้นำเสนอ การนำเอา 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) ได้ที่นี่
|
ขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึง
คุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน
x
|