Results 1 to 5 of 5

Thread: Best way to swap Listview Items?

  1. #1

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    45

    Best way to swap Listview Items?

    As part of a bubble sort of listview items I call a routine that swaps row idx with row idx+1. What I have works, but I know there has to be a much better and quicker way of doing this than the way I am doing it.
    Code:
        Private Sub SwapItems(ByVal idx As Integer)
            Dim Temp0 As String = ""
            Dim Temp1 As String = ""
            Dim Temp2 As String = ""
            Dim Temp3 As String = ""
            Dim Temp4 As String = ""
            Dim Temp5 As String = ""
            Dim Temp6 As String = ""
            Temp0 = ListView1.Items(idx).Text
            Temp1 = ListView1.Items(idx).SubItems(1).Text
            Temp2 = ListView1.Items(idx).SubItems(2).Text
            Temp3 = ListView1.Items(idx).SubItems(3).Text
            Temp4 = ListView1.Items(idx).SubItems(4).Text
            Temp5 = ListView1.Items(idx).SubItems(5).Text
            Temp6 = ListView1.Items(idx).SubItems(6).Text
            ListView1.Items(idx).Text = ListView1.Items(idx + 1).Text
            ListView1.Items(idx).SubItems(1).Text = ListView1.Items(idx + 1).SubItems(1).Text
            ListView1.Items(idx).SubItems(2).Text = ListView1.Items(idx + 1).SubItems(2).Text
            ListView1.Items(idx).SubItems(3).Text = ListView1.Items(idx + 1).SubItems(3).Text
            ListView1.Items(idx).SubItems(4).Text = ListView1.Items(idx + 1).SubItems(4).Text
            ListView1.Items(idx).SubItems(5).Text = ListView1.Items(idx + 1).SubItems(5).Text
            ListView1.Items(idx).SubItems(6).Text = ListView1.Items(idx + 1).SubItems(6).Text
            ListView1.Items(idx + 1).Text = Temp0
            ListView1.Items(idx + 1).SubItems(1).Text = Temp1
            ListView1.Items(idx + 1).SubItems(2).Text = Temp2
            ListView1.Items(idx + 1).SubItems(3).Text = Temp3
            ListView1.Items(idx + 1).SubItems(4).Text = Temp4
            ListView1.Items(idx + 1).SubItems(5).Text = Temp5
            ListView1.Items(idx + 1).SubItems(6).Text = Temp6
        End Sub
    I tried using a temporary ListViewItem to hold the ListView1 item shown below, but I guess you canít directly assign one ListView item to another. It seems you have to completely remove one listview item and then add the other after it as a new item.
    Code:
    Dim TempItem As ListViewItem 
    TempItem = ListView1.Items(idx)
    ListView1.Items(idx) = ListView1.Items(idx + 1)
    ListView1.Items(idx + 1) = TempItem

  2. #2
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    105,187

    Re: Best way to swap Listview Items?

    You should absolutely not be swapping items in the ListView. What you should do is create an array and populate it with all the ListViewItems and then sort the array the same way you would any other array. I would hope that you already know how to bubble sort an array of Integers or Strings. Sorting an array is exactly the same. The only thing that would change is the way you compare two elements of the array. Once you have sorted the array, you could Clear the Items of the ListView and then repopulate it with a single call to AddRange.

    That said, if you really do want to sort in-place then you should actually be swapping items, not the contents of items. Swapping the items at indexes (i) and (i+1) is as simple as this:
    vb.net Code:
    1. Dim item As ListViewItem = ListView1.Items(i + 1)
    2.  
    3. ListView1.Items.Remove(item)
    4. ListView1.Items.Insert(i, item)
    That moves the lower item up. The result is the same but you can also move the upper item down:
    vb.net Code:
    1. Dim item As ListViewItem = ListView1.Items(i)
    2.  
    3. ListView1.Items.Remove(item)
    4. ListView1.Items.Insert(i + 1, item)

  3. #3

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    45

    Re: Best way to swap Listview Items?

    Thanks for the quick reply. Both examples make sense. I didn't think of using an array and rebuilding the listview. Is there any reason you are against sorting in-place? does it take longer to sort that way? It would require less code in your second example.

    Jim

    Quote Originally Posted by jmcilhinney View Post
    You should absolutely not be swapping items in the ListView. What you should do is create an array and populate it with all the ListViewItems and then sort the array the same way you would any other array. I would hope that you already know how to bubble sort an array of Integers or Strings. Sorting an array is exactly the same. The only thing that would change is the way you compare two elements of the array. Once you have sorted the array, you could Clear the Items of the ListView and then repopulate it with a single call to AddRange.

    That said, if you really do want to sort in-place then you should actually be swapping items, not the contents of items. Swapping the items at indexes (i) and (i+1) is as simple as this:
    vb.net Code:
    1. Dim item As ListViewItem = ListView1.Items(i + 1)
    2.  
    3. ListView1.Items.Remove(item)
    4. ListView1.Items.Insert(i, item)
    That moves the lower item up. The result is the same but you can also move the upper item down:
    vb.net Code:
    1. Dim item As ListViewItem = ListView1.Items(i)
    2.  
    3. ListView1.Items.Remove(item)
    4. ListView1.Items.Insert(i + 1, item)

  4. #4
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    105,187

    Re: Best way to swap Listview Items?

    Quote Originally Posted by JimAvanti View Post
    Is there any reason you are against sorting in-place? does it take longer to sort that way?
    I haven't tested this scenario specifically but calling Add repeatedly to add multiple items to a ListView gets exponentially slower because the control redraws after each Add call. I'd expect the same to happen at least once - possibly twice - when you call Remove and Insert. If you really wanted to swap data between items then I'd suggest writing a method or two to do it. You should already have the items themselves because you would have to have compared them to determine that they need to be swapped, so you shouldn't need to work with indexes:
    vb.net Code:
    1. Private Sub SwapListViewItems(item1 As ListViewItem, item2 As ListViewItem)
    2.     Dim text As String
    3.  
    4.     For i = 0 To item1.SubItems.Count - 1
    5.         Dim subitem1 = item1.SubItems(i)
    6.         Dim subitem2 = item2.SubItems(i)
    7.  
    8.         text = subitem1.Text
    9.         subitem1.Text = subitem2.Text
    10.         subitem2.Text = text
    11.     Next
    12. End Sub
    If you must use indexes:
    vb.net Code:
    1. Private Sub SwapListViewItems(index1 As Integer)
    2.     Dim item1 = ListView1.Items(index1)
    3.     Dim item2 = ListView1.Items(index1 + 1)
    4.  
    5.     Dim text As String
    6.  
    7.     For i = 0 To item1.SubItems.Count - 1
    8.         Dim subitem1 = item1.SubItems(i)
    9.         Dim subitem2 = item2.SubItems(i)
    10.  
    11.         text = subitem1.Text
    12.         subitem1.Text = subitem2.Text
    13.         subitem2.Text = text
    14.     Next
    15. End Sub

  5. #5

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    45

    Re: Best way to swap Listview Items?

    jmcilhinney,

    I used your first example and it worked great. It is quicker than how I had it. I don't quite understand how it works though. It seems passing the Listview items into item1 and item2 and swapping them along with the subitems should not actually change the ListView1, but it does. I would have never figured that one out on my own.

    Thanks,
    Jim

    Quote Originally Posted by jmcilhinney View Post
    I haven't tested this scenario specifically but calling Add repeatedly to add multiple items to a ListView gets exponentially slower because the control redraws after each Add call. I'd expect the same to happen at least once - possibly twice - when you call Remove and Insert. If you really wanted to swap data between items then I'd suggest writing a method or two to do it. You should already have the items themselves because you would have to have compared them to determine that they need to be swapped, so you shouldn't need to work with indexes:
    vb.net Code:
    1. Private Sub SwapListViewItems(item1 As ListViewItem, item2 As ListViewItem)
    2.     Dim text As String
    3.  
    4.     For i = 0 To item1.SubItems.Count - 1
    5.         Dim subitem1 = item1.SubItems(i)
    6.         Dim subitem2 = item2.SubItems(i)
    7.  
    8.         text = subitem1.Text
    9.         subitem1.Text = subitem2.Text
    10.         subitem2.Text = text
    11.     Next
    12. End Sub

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width