Hola a todos, quisiera saber como permitir a los usuarios editar los subitems de un listview, ya que con la propiedad LabelEdit sólo se pueden editar los items, aquí les dejo un ejemplo para que se vea mejor
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim C As Integer
ListView1.View = View.Details
ListView1.Columns.Add("Items")
ListView1.Columns.Add("SubItems", 70)
ListView1.FullRowSelect = True
ListView1.GridLines = True
'A pesar que permito modificar los items,
'no me lo permite para los subitems, que es lo que quiero hacer.
ListView1.LabelEdit = True
For C = 0 To 20
ListView1.Items.Add("Prueba " & C)
ListView1.Items(C).SubItems.Add("SubItem " & C)
Next
End Sub
Esa es una limitación del control ListView, por lo tanto es algo que debes implementar por ti mismo.
Te he escrito el siguiente ejemplo funcional (para editar una celda o subitem haz doble-click):
Friend WithEvents TextBoxLvItem As TextBox
Private currentItem As ListViewSubItem
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.TextBoxLvItem = New TextBox With {.Visible = False}
Me.Controls.Add(Me.TextBoxLvItem)
End Sub
Private Sub ListView1_MouseClick(ByVal sender As Object, ByVal e As MouseEventArgs) _
Handles ListView1.MouseClick
Me.TextBoxLvItem.Hide()
End Sub
Private Sub ListView1_MouseDoubleClick(ByVal sender As Object, ByVal e As MouseEventArgs) _
Handles ListView1.MouseDoubleClick
Dim lv As ListView = DirectCast(sender, ListView)
Dim hitTest As ListViewHitTestInfo = lv.HitTest(e.X, e.Y)
Me.currentItem = hitTest.SubItem
With Me.TextBoxLvItem
.Width = lv.Columns(hitTest.Item.Index).Width
.Left = (lv.Left + hitTest.SubItem.Bounds.Left + 3)
.Top = (lv.Top + hitTest.SubItem.Bounds.Top)
.Text = hitTest.SubItem.Text
.Show()
.Focus()
.SelectAll()
End With
lv.SendToBack()
End Sub
Private Sub TextBoxLvItem_KeyUp(ByVal sender As Object, ByVal e As KeyEventArgs) _
Handles TextBoxLvItem.KeyUp
Select Case e.KeyData
Case Keys.Return ' Guardar el texto.
currentItem.Text = DirectCast(sender, TextBox).Text
DirectCast(sender, TextBox).Hide()
Case Keys.Escape ' No guardar el texto.
DirectCast(sender, TextBox).Hide()
Case Else
'...
End Select
End Sub
PD: No actives el LabelEdit, no es necesario con el código que mostré.
Saludos
Tengo en el listview dos columnas y 20 items, cada item tiene un subitem. Cuando el index del elemento es menor o igual que el index de la última columna funciona bien, pero cuando el el index del elemento es mayor que el index de la última columna, ejemplo: doy docble clic en un item o subitem de index >=3 da el siguiente error:
'InvalidArgument=El valor de '4' no es válido para 'index'.
'Nombre del parámetro: index
.Width = lv.Columns(hitTest.Item.Index).Width
Cita de: Eleкtro en 8 Enero 2016, 19:16 PM
Esa es una limitación del control ListView, por lo tanto es algo que debes implementar por ti mismo.
Te he escrito el siguiente ejemplo funcional (para editar una celda o subitem haz doble-click):
Friend WithEvents TextBoxLvItem As TextBox
Private currentItem As ListViewSubItem
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.TextBoxLvItem = New TextBox With {.Visible = False}
Me.Controls.Add(Me.TextBoxLvItem)
End Sub
Private Sub ListView1_MouseClick(ByVal sender As Object, ByVal e As MouseEventArgs) _
Handles ListView1.MouseClick
Me.TextBoxLvItem.Hide()
End Sub
Private Sub ListView1_MouseDoubleClick(ByVal sender As Object, ByVal e As MouseEventArgs) _
Handles ListView1.MouseDoubleClick
Dim lv As ListView = DirectCast(sender, ListView)
Dim hitTest As ListViewHitTestInfo = lv.HitTest(e.X, e.Y)
Me.currentItem = hitTest.SubItem
With Me.TextBoxLvItem
.Width = lv.Columns(hitTest.Item.Index).Width
.Left = (lv.Left + hitTest.SubItem.Bounds.Left + 3)
.Top = (lv.Top + hitTest.SubItem.Bounds.Top)
.Text = hitTest.SubItem.Text
.Show()
.Focus()
.SelectAll()
End With
lv.SendToBack()
End Sub
Private Sub TextBoxLvItem_KeyUp(ByVal sender As Object, ByVal e As KeyEventArgs) _
Handles TextBoxLvItem.KeyUp
Select Case e.KeyData
Case Keys.Return ' Guardar el texto.
currentItem.Text = DirectCast(sender, TextBox).Text
DirectCast(sender, TextBox).Hide()
Case Keys.Escape ' No guardar el texto.
DirectCast(sender, TextBox).Hide()
Case Else
'...
End Select
End Sub
PD: No actives el LabelEdit, no es necesario con el código que mostré.
Saludos
Tienes razón, un fallo tonto. La manera correcta de obtener el índice de la columna sería la siguiente:
Dim columnindex As Integer = hitTest.Item.SubItems.IndexOf(hitTest.SubItem)
Con eso ya puedes solucionar el problema.
Por cierto, de nada.
Saludos!
Ahora si quedo perfecto ;-)
Cita de: Eleкtro en 8 Enero 2016, 20:37 PM
Tienes razón, un fallo tonto. La manera correcta de obtener el índice de la columna sería la siguiente:
Dim columnindex As Integer = hitTest.Item.SubItems.IndexOf(hitTest.SubItem)
Con eso ya puedes solucionar el problema.
Por cierto, de nada.
Saludos!