We help IT Professionals succeed at work.

Drag and Drop between two listviews (in 'Details' view)

799 Views
Last Modified: 2013-11-27
I have a windows application in which I need to set up a drag and drop function between two listviews. Each listview has two columns. All I can find on the internet is how to do it in 'List' view, but I need the listviews to be in 'Details' view. Here is the code that I found to do it in 'List' view:

    Private Sub ListView_ItemDrag(ByVal sender As Object, ByVal e As _
    System.Windows.Forms.ItemDragEventArgs) Handles AccountsLV.ItemDrag, _
    AssetsLV.ItemDrag
        Dim myItem As ListViewItem
        Dim myItems(sender.SelectedItems.Count - 1) As ListViewItem
        Dim i As Integer = 0

        ' Loop though the SelectedItems collection for the source.
        For Each myItem In sender.SelectedItems
            ' Add the ListViewItem to the array of ListViewItems.
            myItems(i) = myItem
            i = i + 1
        Next
        ' Create a DataObject containg the array of ListViewItems.
        sender.DoDragDrop(New _
        DataObject("System.Windows.Forms.ListViewItem()", myItems), _
        DragDropEffects.Move)
    End Sub

    Private Sub ListView_DragEnter(ByVal sender As Object, ByVal e As _
    System.Windows.Forms.DragEventArgs) Handles AccountsLV.DragEnter, AssetsLV.DragEnter
        ' Check for the custom DataFormat ListViewItem array.
        If e.Data.GetDataPresent("System.Windows.Forms.ListViewItem()") Then
            e.Effect = DragDropEffects.Move
        Else
            e.Effect = DragDropEffects.None
        End If
    End Sub

    Private Sub ListView_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles AccountsLV.DragDrop, AssetsLV.DragDrop
        Dim myItem As ListViewItem
        Dim myItems() As ListViewItem = e.Data.GetData("System.Windows.Forms.ListViewItem()")
        Dim i As Integer = 0

        For Each myItem In myItems
            ' Add the item to the target list.
            sender.Items.Add(myItems(i).Text)
            ' Remove the item from the source list.
            If sender Is AccountsLV Then
                AssetsLV.Items.Remove(AssetsLV.SelectedItems.Item(0))
            Else
                AccountsLV.Items.Remove(AccountsLV.SelectedItems.Item(0))
            End If
            i = i + 1

        Next
    End Sub



I also found the following code which allows me to add items in the second listview with a button click event:

    Private Sub ToolStripButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton1.Click
        For Each item As ListViewItem In AccountsLV.SelectedItems
            Dim newItem As ListViewItem = CType(item.Clone(), ListViewItem)
            AssetsLV.Items.Add(newItem)
        Next
    End Sub

Is there anyway to combine the two somehow so that I can do a drag and drop, in 'Details' view?
Comment
Watch Question

Trying to understand, you are able to drag and drop using the other views but not able to do the same with Details View?

Author

Commented:
Yes, correct

Commented:
Can you explain some more, because looking at the code it would work in details view to. Can you show us the code where you setup the listviews?

Author

Commented:
It works, but all it is transferring is column 1.... I need both columns to transfer

Commented:
You need to iterate the subitems e.g.

Private Sub ListView_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles AccountsLV.DragDrop, AssetsLV.DragDrop
        Dim myItem As ListViewItem
        Dim myItems() As ListViewItem = e.Data.GetData("System.Windows.Forms.ListViewItem()")
        Dim i As Integer = 0

        For Each myItem In myItems

            ' Add the item to the target list.
           Dim itmX as new listviewitem

          itmX.Text = myItems(i).Text

         for ctr as integer = 0 to myItems(i).subitems.count - 1
             
               itmX.Subitems.add(myItems(i).subitems(ctr).tostring              

        next ctr

            sender.Items.Add(itmX)

            ' Remove the item from the source list.
            If sender Is AccountsLV Then
                AssetsLV.Items.Remove(AssetsLV.SelectedItems.Item(0))
            Else
                AccountsLV.Items.Remove(AccountsLV.SelectedItems.Item(0))
            End If
            i = i + 1

        Next
    End Sub

Author

Commented:
In Column 2, instead of adding the subitem text, it adds:

ListViewSubitem: {R0120006}
ListViewSubitem: {R0120009}
etc.

R0120006 and R0120009 are the items in column 1

Any idea how to fix this?

Commented:
sorry the line should be

itmX.Subitems.add(myItems(i).subitems(ctr)

(Without the ToString)

Author

Commented:
Now it is just repeating the items that are in column 1 in column 2:

R0120006   R0120006
R0120009   R0120009

Commented:
Okay I double checked are you sure you have coded it right, as in you used the 'ctr' variable?

for ctr as integer = 0 to myItems(i).subitems.count - 1
             
               itmX.Subitems.add(myItems(i).subitems(ctr).tostring)              

        next ctr

YOU DO NEED the ToString [My mistake, not reading the code)

Commented:
Paste your code here again please

Author

Commented:
It went back to doing:

 Column 2, instead of adding the subitem text, it adds:

ListViewSubitem: {R0120006}
ListViewSubitem: {R0120009}
etc.

R0120006 and R0120009 are the items in column 1

here is my code:


Private Sub ListView_ItemDrag(ByVal sender As Object, ByVal e As _
    System.Windows.Forms.ItemDragEventArgs) Handles AccountsLV.ItemDrag, _
    ListView1.ItemDrag
        Dim myItem As ListViewItem
        Dim myItems(sender.SelectedItems.Count - 1) As ListViewItem
        Dim i As Integer = 0

        ' Loop though the SelectedItems collection for the source.
        For Each myItem In sender.SelectedItems
            ' Add the ListViewItem to the array of ListViewItems.
            myItems(i) = myItem
            i = i + 1
        Next
        ' Create a DataObject containg the array of ListViewItems.
        sender.DoDragDrop(New _
        DataObject("System.Windows.Forms.ListViewItem()", myItems), _
        DragDropEffects.Move)
    End Sub

    Private Sub ListView_DragEnter(ByVal sender As Object, ByVal e As _
    System.Windows.Forms.DragEventArgs) Handles AccountsLV.DragEnter, ListView1.DragEnter
        ' Check for the custom DataFormat ListViewItem array.
        If e.Data.GetDataPresent("System.Windows.Forms.ListViewItem()") Then
            e.Effect = DragDropEffects.Move
        Else
            e.Effect = DragDropEffects.None
        End If
    End Sub
    Private Sub ListView_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles AccountsLV.DragDrop, ListView1.DragDrop
        Dim myItem As ListViewItem
        Dim myItems() As ListViewItem = e.Data.GetData("System.Windows.Forms.ListViewItem()")
        Dim i As Integer = 0
        For Each myItem In myItems
            ' Add the item to the target list.
            Dim itmX As New ListViewItem
            itmX.Text = myItems(i).Text
            For ctr As Integer = 0 To myItems(i).SubItems.Count - 1
                itmX.SubItems.Add(myItems(i).SubItems(ctr).ToString)
            Next ctr
            sender.Items.Add(itmX)
            ' Remove the item from the source list.
            If sender Is AccountsLV Then
                ListView1.Items.Remove(ListView1.SelectedItems.Item(0))
            Else
                AccountsLV.Items.Remove(AccountsLV.SelectedItems.Item(0))
            End If
            i = i + 1
        Next
    End Sub

Commented:
Hi I am really confused. Does the target listview have 2 columns?

Please do this:

itmX.Text = myItems(i).Text
Debug.WriteLine(itmX.Text)

            For ctr As Integer = 0 To myItems(i).SubItems.Count - 1
                itmX.SubItems.Add(myItems(i).SubItems(ctr).ToString)

               Debug.WriteLine(myItems(i).SubItems(ctr).ToString)

            Next ctr

Now does the output in the immediate window do as expected? e.g you get the right data in the right columns?

Author

Commented:
I am still getting:

In Column 2, instead of adding the subitem text, it adds:

ListViewSubitem: {R0120006}
ListViewSubitem: {R0120009}
etc.

R0120006 and R0120009 are the items in column 1
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

Commented:
still doing it... I have no idea why

Commented:
Can you post the code that you use to populate the listview items where they are being dragged from please?

Author

Commented:
I am pulling the information from excel:
(oSheet is the variable I am using for the excel sheet)

        Dim rowsA As Long = oSheet.Cells(oSheet.Rows.Count, 2).End(xlUp).Row
        Dim i As Long
        For i = 1 To rowsA
            Dim MyItem As New ListViewItem
            MyItem = AccountsLV.Items.Add(oSheet.Cells(i, 2).Value, 0)
            MyItem.SubItems.Add(oSheet.Cells(i, 3).Value)
        Next

Commented:
Oh how stupid of me! DOH!

Sorry what the line in the listitem reference to the subitem should be [.Text]:

 Private Sub ListView_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles AccountsLV.DragDrop, ListView1.DragDrop
        Dim myItem As ListViewItem
        Dim myItems() As ListViewItem = e.Data.GetData("System.Windows.Forms.ListViewItem()")
        Dim i As Integer = 0
        For Each myItem In myItems
            ' Add the item to the target list.
            Dim itmX As New ListViewItem
            itmX.Text = myItems(i).Text
            For ctr As Integer = 0 To myItems(i).SubItems.Count - 1
                itmX.SubItems.Add(myItems(i).SubItems(ctr).Text)
            Next ctr
            sender.Items.Add(itmX)
            ' Remove the item from the source list.
            If sender Is AccountsLV Then
                ListView1.Items.Remove(ListView1.SelectedItems.Item(0))
            Else
                AccountsLV.Items.Remove(AccountsLV.SelectedItems.Item(0))
            End If
            i = i + 1
        Next
    End Sub

Author

Commented:
This is a horrible cycle... now it is giving me the same value from column 1 in column 2:

R0120006   R0120006
R0120009   R0120009

Here is my code:

Private Sub ListView_ItemDrag(ByVal sender As Object, ByVal e As _
        System.Windows.Forms.ItemDragEventArgs) Handles AccountsLV.ItemDrag, _
        ListView1.ItemDrag
        Dim myItem As ListViewItem
        Dim myItems(sender.SelectedItems.Count - 1) As ListViewItem
        Dim i As Integer = 0
        ' Loop though the SelectedItems collection for the source.
        For Each myItem In sender.SelectedItems
            ' Add the ListViewItem to the array of ListViewItems.
            myItems(i) = myItem
            For ctr As Integer = 0 To myitem.subitems.count - 1
                myItems(i).SubItems.Add(myItem.SubItems(ctr).ToString)
            Next ctr
            i = i + 1
        Next
        ' Create a DataObject containg the array of ListViewItems.
        sender.DoDragDrop(New _
        DataObject("System.Windows.Forms.ListViewItem()", myItems), _
        DragDropEffects.Move)
    End Sub

    Private Sub ListView_DragEnter(ByVal sender As Object, ByVal e As _
    System.Windows.Forms.DragEventArgs) Handles AccountsLV.DragEnter, ListView1.DragEnter
        ' Check for the custom DataFormat ListViewItem array.
        If e.Data.GetDataPresent("System.Windows.Forms.ListViewItem()") Then
            e.Effect = DragDropEffects.Move
        Else
            e.Effect = DragDropEffects.None
        End If
    End Sub
    Private Sub ListView_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles AccountsLV.DragDrop, ListView1.DragDrop
        Dim myItem As ListViewItem
        Dim myItems() As ListViewItem = e.Data.GetData("System.Windows.Forms.ListViewItem()")
        Dim i As Integer = 0
        For Each myItem In myItems
            ' Add the item to the target list.
            Dim itmX As New ListViewItem
            itmX.Text = myItems(i).Text
            For ctr As Integer = 0 To myItems(i).SubItems.Count - 1
                itmX.SubItems.Add(myItems(i).SubItems(ctr).Text)
            Next ctr
            sender.Items.Add(itmX)
            ' Remove the item from the source list.
            If sender Is AccountsLV Then
                ListView1.Items.Remove(ListView1.SelectedItems.Item(0))
            Else
                AccountsLV.Items.Remove(AccountsLV.SelectedItems.Item(0))
            End If
            i = i + 1
        Next
    End Sub
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

Commented:
IT WORKED! Thanks so much for your patience

Commented:
Oh I just love horrible cycles, they make my day when you get out of them!

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.