As I was finishing off the previous blog item on the Windows Forms ListView, it occurred to me that there isn't much documentation around to explain how to edit the ListView items. So I thought it might be useful to cover a couple of approaches in this blog.
If you're disappointed that there isn't a built-in way to edit all the items and sub items, the thing to bear in mind is that ListView is essentially a display control, rather than an editing one. That said, there is one built-in tool that you can use - but only as long as you are content to edit items in the first column exclusively.
Edit First Column Only
What you can do is set the ListView's LabelEdit property to True. You can set this via the Properties Window or in code, ideally in the Load Event:
Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
LVMVPs.LabelEdit = True
End Sub
Now, if you click on an item in the first column on any row, the data in the first column of the selected row will become editable. I actually found that I had to triple-click, but I'm not sure if this is just a reflection of my mouse click speed settings or is the default requirement:

If you have the FullRowSelect property set to True, you can click anywhere along the row and the item in the first column will become editable as shown in the screenshot above. If FullRowSelect is set to False then you do need to click directly on the first column.

Edit Any Column
You have to do a bit of work yourself if you want to be able to edit any cell in the ListView, but there isn't really much to it. To demonstrate the technique, I've added three TextBoxes and an Update button to the Form:

The code below will allow the user to Right-click on any row and this will cause the three items of data in that row to be displayed in the three TextBoxes.
Dim ItemSelected As ListViewItem
Private Sub LVMVPs_MouseDown(ByVal sender As Object, _
ByVal e As MouseEventArgs) Handles LVMVPs.MouseDown
' Test that user wants to edit
If e.Button = Windows.Forms.MouseButtons.Right Then
' Identify the selected ListViewItem
ItemSelected = LVMVPs.GetItemAt(e.X, e.Y)
' Display in TextBoxes to allow editing
If (ItemSelected IsNot Nothing) Then
TextBox1.Text = (ItemSelected.SubItems(0).Text)
TextBox2.Text = (ItemSelected.SubItems(1).Text)
TextBox3.Text = (ItemSelected.SubItems(2).Text)
End If
End If
End Sub
As you can see, it first tests that the Right mouse button has been clicked and if it has then each of the sub items is pasted into an individual TextBox below. The key feature in this block of code is the GetItemAt method of the ListView. This is the magic ingredient that allows you to easily identify exactly which row the user wants to deal with (and if you've spent a lot of fruitless time trying to work out how to use other ListView selection methods, you'll be pleased that you landed here!). Note that ItemSelected (the variable I am using to hold the current selection) is a ListViewItem object, not an index number - which is where most people seem to get caught.
The Confirm code is also very simple.
Private Sub btnConfirm_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConfirm.Click
' Update ListView
ItemSelected.SubItems(0).Text = TextBox1.Text
ItemSelected.SubItems(1).Text = TextBox2.Text
ItemSelected.SubItems(2).Text = TextBox3.Text
' Avoid confusion by clearing TextBoxes
TextBox1.Clear()
TextBox2.Clear()
TextBox3.Clear()
End Sub
The content of each TextBox is transferred back to the relevant ListView sub item (regardless of whether it has been changed - although you could of course build in a filter here if you wanted to). The TextBoxes are then cleared.
And for a simple project, that's really all there is to it. As you can see, I did also add a button to clear the ListView, but that was just for my own convenience, so I could test multiple consecutive edits without duplicating the data in the file.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
LVMVPs.Clear()
End Sub
Not so obviously, I did also make a change to the file save code. I wanted to ensure that there wasn't a new blank line at the end of the text file, which might have caused a problem, so I tweaked the btnSave Click event as shown below:
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
' Create FileStream and StreamWriter to access and write to file
Dim FS As New FileStream(TextFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)
Dim SW As New StreamWriter(FS)
Try
' Loop through all rows
For Index As Integer = 0 To LVMVPs.Items.Count - 1
' Internally loop through all columns, gathering items
For SubIndex As Integer = 0 To LVMVPs.Items(Index).SubItems.Count - 1
SW.Write(LVMVPs.Items(Index).SubItems(SubIndex).Text & Chr(9))
Next
' Create new line ready for next row
' except for final entry
If Index = LVMVPs.Items.Count - 1 Then
Exit For
Else
SW.Write(Environment.NewLine)
End If
Next
Catch ex As Exception
MsgBox("Error saving to file." & ex.Message)
Finally
SW.Close()
FS.Close()
End Try
End Sub
To avoid errors when there is no data in the TextBoxes, you might also want to disable and enable the Confirm button when appropriate. The sample project which you can download from here, includes this feature.