Class EditPanel
Inherits Panel
Private WithEvents LB As ListView
Private UbC As Integer, Txb() As TextBox, Activate As Boolean
Sub New(ByRef Listbox As ListView)
LB = Listbox
Me.Hide()
LB.Controls.Add(Me)
End Sub
Private Sub ChangeWidth(sender As Object, e As ColumnWidthChangingEventArgs) Handles LB.ColumnWidthChanging
Dim SLf As Integer
If Activate Then
Application.DoEvents()
For I As Integer = 0 To e.ColumnIndex - 1
SLf += LB.Columns(I).Width
Next
For I As Integer = e.ColumnIndex To UbC
With Txb(I)
.Left = SLf
If I >= e.ColumnIndex Then
.Width = LB.Columns(I).Width
End If
End With
SLf += LB.Columns(I).Width
Next
Me.Width = LB.Width
End If
End Sub
Private Function MouseIsOverControl(ByVal c As Control) As Boolean
Return c.ClientRectangle.Contains(c.PointToClient(Control.MousePosition))
End Function
Private Sub ShowMe(sender As Object, e As EventArgs) Handles LB.DoubleClick
Dim rc As Rectangle = LB.FocusedItem.GetBounds(ItemBoundsPortion.Entire)
Dim Lf, Tp, Ht As Integer
Tp = rc.Top
Lf = LB.Left + rc.Left
Ht = rc.Height
UbC = LB.Columns.Count - 1
With Me
.Controls.Clear()
Dim SLf As Integer
ReDim Txb(UbC)
For i As Integer = 0 To UbC
Txb(i) = New TextBox
With Txb(i)
.Text = LB.FocusedItem.SubItems(i).Text
.Left = SLf
.Width = LB.Columns(i).Width
SLf += LB.Columns(i).Width
End With
.Controls.Add(Txb(i))
Next
.Left = Lf
.Top = Tp
.Height = Ht + 1
.Width = LB.Width
Activate = True
.Show()
Dim Txtb As TextBox = Nothing
For Each ctrl As Control In .Controls
If TypeOf ctrl Is TextBox Then
Txtb = DirectCast(ctrl, TextBox)
AddHandler Txtb.KeyPress, AddressOf Me.EnterValue
If MouseIsOverControl(ctrl) Then ctrl.Select()
End If
Next
End With
End Sub
Sub EnterValue(sender As TextBox, e As KeyPressEventArgs)
If e.KeyChar = vbCr Then
LB.FocusedItem.SubItems(sender.TabIndex).Text = sender.Text
HideMe(sender, e)
End If
End Sub
Private Sub HideMe(sender As Object, e As EventArgs) Handles Me.LostFocus, LB.ItemSelectionChanged
Me.Hide()
Activate = False
End Sub
End Class
Class EditPanel
Inherits Panel
Private WithEvents LB As ListView
Private UbC As Integer, Txb() As TextBox, Activate As Boolean, sortColumn As Integer = -1
Sub New(ByRef Listbox As ListView)
LB = Listbox
Me.Hide()
With LB
.Controls.Add(Me)
.GridLines = True
.FullRowSelect = True
End With
End Sub
Private Sub ChangeWidth(sender As Object, e As ColumnWidthChangingEventArgs) Handles LB.ColumnWidthChanging
Dim SLf As Integer
If Activate Then
Application.DoEvents()
For I As Integer = 0 To e.ColumnIndex - 1
SLf += LB.Columns(I).Width
Next
For I As Integer = e.ColumnIndex To UbC
With Txb(I)
.Left = SLf
.Width = LB.Columns(I).Width
End With
SLf += LB.Columns(I).Width
Next
Me.Width = LB.Width
End If
End Sub
Private Function MouseIsOverControl(ByVal c As Control) As Boolean
Return c.ClientRectangle.Contains(c.PointToClient(Control.MousePosition))
End Function
Private Sub ShowMe(sender As Object, e As EventArgs) Handles LB.DoubleClick
Dim rc As Rectangle = LB.FocusedItem.GetBounds(ItemBoundsPortion.Entire)
Dim Lf, Tp, Ht As Integer
Tp = rc.Top
Lf = LB.Left + rc.Left
Ht = rc.Height
UbC = LB.Columns.Count - 1
With Me
.Controls.Clear()
Dim SLf As Integer
ReDim Txb(UbC)
For i As Integer = 0 To UbC
Txb(i) = New TextBox
With Txb(i)
.Text = LB.FocusedItem.SubItems(i).Text
.Left = SLf
.Width = LB.Columns(i).Width
SLf += LB.Columns(i).Width
End With
.Controls.Add(Txb(i))
Next
.Left = Lf
.Top = Tp
.Height = Ht + 1
.Width = LB.Width
Activate = True
.Show()
Dim Txtb As TextBox = Nothing
For Each ctrl As Control In .Controls
If TypeOf ctrl Is TextBox Then
Txtb = DirectCast(ctrl, TextBox)
AddHandler Txtb.KeyPress, AddressOf Me.EnterValue
If MouseIsOverControl(ctrl) Then ctrl.Select()
End If
Next
End With
End Sub
Private Sub LB_ColumnClick(sender As Object, e As ColumnClickEventArgs) Handles LB.ColumnClick
If e.Column <> sortColumn Then
sortColumn = e.Column
LB.Sorting = SortOrder.Ascending
Else
If LB.Sorting = SortOrder.Ascending Then
LB.Sorting = SortOrder.Descending
Else
LB.Sorting = SortOrder.Ascending
End If
End If
LB.Sort()
LB.ListViewItemSorter = New ListViewItemComparer(e.Column, LB.Sorting)
End Sub
Private Sub EnterValue(sender As TextBox, e As KeyPressEventArgs)
If e.KeyChar = vbCr Then
LB.FocusedItem.SubItems(sender.TabIndex).Text = sender.Text
HideMe(sender, e)
ElseIf e.KeyChar = Chr(27) Then
HideMe(sender, e)
End If
End Sub
Private Sub HideMe(sender As Object, e As EventArgs) Handles Me.Leave
Me.Hide()
Activate = False
End Sub
End Class
ครับ
นี่เป็น Class ที่ผมกับการปรับปรุงเพิ่มเติมครับ
สิ่งที่เพิ่มคือ ฟอร์มแมตมุมมองให้เป็น Details + GridLine + FullRowSelect เมื่อประกาศ Class EditPanel ด้วย New
เพื่อไม่ต้องเขียนคำสั่งภายนอกคลาส
Code (VB.NET)
Sub New(ByRef Listbox As ListView)
LB = Listbox
Me.Hide()
With LB
.Controls.Add(Me)
.GridLines = True
.FullRowSelect = True
End With
End Sub