Click here to Skip to main content
15,868,141 members
Articles / Desktop Programming / Win32
Tip/Trick

How to Edit ListViewItems Directly

Rate me:
Please Sign up or sign in to vote.
4.60/5 (3 votes)
5 Apr 2013CPOL 15.7K   8   3
Easy way to edit the right ListViewItem (Row/Column) after MouseDoubleClick.

Introduction

This code should help solve an old topic in a smart way I think.

Requirement for this is a ListView configured as follows:

required:

  • View = Details

optional:

  • GridLines = True
  • FullRowSelect = True

Background

  • Dynamical Creation of Controls in case textBox
  • Dynamical Addition of Handlers

Using the Code

I'm working with SharpDevelop 4.2, Framework 4.0 and used the Event "MouseDoubleClick" of the ListView1.

Here is my code:

VB.NET
    Sub ListView1MouseDoubleClick(sender As Object, e As MouseEventArgs)
        'get the Index of the ItemRow and the ItemColumn
        Dim RowColumn As Integer() = GET_RowColumn(listView1, New Point(e.X, e.Y))
        'create the dynamical Text
        Dim TmpTXT1 As New TextBox
        
        'Add the TextBox to the ListView1
        listView1.Controls.Add(TmpTXT1)
        
        'Configure the Settings of the TextBox
        With TmpTXT1
            .Location = New Point(e.X, e.Y)
            .Size = New Size(100, 23)
            
            'Prevent an Exception and check if ListViewItem already has the selected SubItem
            'Please note that ListView1.Items.Item(0).Text
            'is the same like ListView1.Items.Item(0).SubItems.Item(0).Text
            'So each ListViewItem WITHOUT a SubItem has a SubItems.Count of 1 anyway.
            If listView1.Items.Item(RowColumn(0)).SubItems.Count - 1 >= RowColumn(1) Then
                .Text = listView1.Items.Item(RowColumn(0)).SubItems.Item(RowColumn(1)).Text
            Else
                'If Not add them automatically 'OnClick' to be able to edit the Item
                Do While listView1.Items.Item(RowColumn(0)).SubItems.Count <= RowColumn(1) 
                    listView1.Items.Item(RowColumn(0)).SubItems.Add("")
                Loop
                .Text = listView1.Items.Item(RowColumn(0)).SubItems.Item(RowColumn(1)).Text
            End If
            
            'Show Options
            .Show()
            .BringToFront()
            'For Faster editing directly after the double click
            .Focus()
            .SelectAll()
            
            'Create dynamical Event Handlers
            AddHandler .PreviewKeyDown, AddressOf TmpTXT1_PreviewKeyDown
            AddHandler .LostFocus, AddressOf TmpTXT1_LostFocus
        End With
    End Sub

''' <summary>
''' Gets the row and column index of the currently selected ListViewItem.
''' </summary>
''' <returns>Returns an Integer array (Row Index, Column Index)</returns>
Function GET_RowColumn(ByVal LView As ListView, ByVal Position As Point) As Integer()
        'Find Item and SubItem with the help of the MousePosition
        Dim TmpHTI1 As ListViewHitTestInfo = LView.HitTest(Position)
        'Create the Integer Array
        Dim RowColumn(2) As Integer
        
        'Now Indexes are easy to set
        RowColumn(0) = TmpHTI1.Item.Index
        RowColumn(1) = TmpHTI1.Item.SubItems.IndexOf(TmpHTI1.SubItem)
        
        'Return the result
        Return RowColumn
End Function

Sub TmpTXT1_PreviewKeyDown(ByVal sender As Object, ByVal e As PreviewKeyDownEventArgs)
    'Define the correct type of the sender
    Dim TmpTXT1 As TextBox = CType(sender, TextBox)
    'Get the ListViewItem Location again by reference to the location of the textBox.
    'Btw. This is why we need to create the TextBox 
    'at the same Location than the original Mouseposition.
    Dim RowColumn As Integer() = GET_RowColumn(listView1, TmpTXT1.Location)
    'when we press Enter the text would be applied to the ListViewItem
    If e.KeyCode = Keys.Enter Then
        listView1.Items.Item(RowColumn(0)).SubItems.Item_
        (RowColumn(1)).Text = CType(sender, TextBox).Text
        CType(sender, TextBox).dispose()
    'with Esc we can exit the edit without saving the changes
    ElseIf e.KeyCode = Keys.Escape Then
        CType(sender, TextBox).dispose()
    End If
End Sub

Sub TmpTXT1_LostFocus(ByVal sender As Object, ByVal e As EventArgs)
    'we also are able to get out by clicking somewhere else and lose the focus to the textbox
    CType(sender, TextBox).dispose()
End Sub
 

History

  • Version 1.0
  • Version 1.1 - Added a loop which creates new empty SubItem(s) automatically 'OnClick' to prevent Exceptions with ListViewItems which have no SubItem yet. Thanks to BertrandLQ
  • Version 1.2 - Found out that the previous Version of the Function GET_RowColumn does not work correctly with ListViews which are scrolled horizontal (e.g. small window but a big table width). ListViewHitTestInfo finds the visual position of a ListViewItem and gives the correct Row/Column Index back regardless of scrolling the ListView horizontal or not.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Shahan Ayyub26-Mar-13 7:47
Shahan Ayyub26-Mar-13 7:47 
Thanks for sharing it
GeneralMy vote of 5 Pin
BertrandLQ25-Mar-13 23:46
BertrandLQ25-Mar-13 23:46 
AnswerRe: My vote of 5 Pin
dapeacenforcement28-Mar-13 1:36
dapeacenforcement28-Mar-13 1:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.