• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 701
  • Last Modified:

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

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?
0
tiehaze
Asked:
tiehaze
  • 11
  • 10
2 Solutions
 
surajgupthaCommented:
Trying to understand, you are able to drag and drop using the other views but not able to do the same with Details View?
0
 
tiehazeAuthor Commented:
Yes, correct
0
 
RainUKCommented:
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?
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
tiehazeAuthor Commented:
It works, but all it is transferring is column 1.... I need both columns to transfer
0
 
RainUKCommented:
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
0
 
tiehazeAuthor 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?
0
 
RainUKCommented:
sorry the line should be

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

(Without the ToString)
0
 
tiehazeAuthor Commented:
Now it is just repeating the items that are in column 1 in column 2:

R0120006   R0120006
R0120009   R0120009
0
 
RainUKCommented:
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)
0
 
RainUKCommented:
Paste your code here again please
0
 
tiehazeAuthor 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
0
 
RainUKCommented:
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?
0
 
tiehazeAuthor 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
0
 
RainUKCommented:
I can only think that the copy of the listview item in the item drag event does not contain the subitems collection for each item. Hence you can try to write a debug statement to check or alter:

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
0
 
tiehazeAuthor Commented:
still doing it... I have no idea why
0
 
RainUKCommented:
Can you post the code that you use to populate the listview items where they are being dragged from please?
0
 
tiehazeAuthor 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
0
 
RainUKCommented:
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
0
 
tiehazeAuthor 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
0
 
RainUKCommented:
Offset the ctr by 1, it includes the .Text in the listviewitem as the first subitem for some reason.

e.g. For ctr As Integer = 1 To myItems(i).SubItems.Count - 1

So change it to :

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 = 1 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
0
 
tiehazeAuthor Commented:
IT WORKED! Thanks so much for your patience
0
 
RainUKCommented:
Oh I just love horrible cycles, they make my day when you get out of them!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 11
  • 10
Tackle projects and never again get stuck behind a technical roadblock.
Join Now