Hello everyone,

this might be a common question with a pretty regular answer "No It can't be done in VB.NET", but still - I'm developing an app which has a File Manager inside It...

My File manager are 2 Listview's with displaying & operating same as Windows Explorer (icons,column sorting, different views, drag&drop etc...). I'm also using a right-click context menu for Cut/Copy/Paste operations. Desired output is to do same operations as in Windows Explorer - meaning that you can Cut/Copy/Paste from app to Windows and vice versa too - like If you would open 3 Window Explorer windows and operate Copy/Move of files/folders/images etc.

The only problem is ofcourse detecting Paste operation, specially after Cut when I need to remove "Item which was Cut" from my Listview, after Paste. I figured out that in Windows, after you do Cut/Paste operation, clipboard get's cleared (but I don't have a clue what attribute tells Explorer that) - so basically all you need is to let Clipboard know that files will be moved. Taking that in consideration I did this:

1. Created function for Clipboard, using "Preferred DropEffect" to set Move/Copy for file collections (and another function one to check dropeffect)
2. Created a function to reload directory currently viewing in Listview (with inherited double-buffered Listview to prevent flickering)
3. Implemented Cut operation code, and placed a Timer on my form.

My code (Cut operation code and Timer1):

Code:
Dim FileCollection As New System.Collections.Specialized.StringCollection()
Dim Lview_ItemsCount As Integer

    Private Sub CutToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles CutToolStripMenuItem.Click

        'Delete any files in our Specialized string collection
        FileCollection.Clear()

        'MenuControl is a variable which tells me on which Listview I opened context menu
        If MenuControl Is Listview1 Or MenuControl Is Listview2 Then

            'Set Listview of context-menu 
            Dim Lview As System.Windows.Forms.ListView
            Lview = MenuControl

            'Add all selected item tags to clipboard here - and mark each item with Backcolor.InactiveBorder
            For Each item As ListViewItem In Lview.SelectedItems
                If File.Exists(item.Tag.ToString) Or Directory.Exists(item.Tag.ToString) Then
                    
                    FileCollection.Add(item.Tag.ToString)
                    Clipboard.SetFileDropList(FileCollection)
                    item.BackColor = SystemColors.InactiveBorder

                    'Set DropEffect = Move to Clipboard with function
                    Set_CopyMove({2, 0, 0, 0}, FileCollection)
                    
                    'And save number of Listview Items into a variable
                    Lview_ItemsCount = Lview.Items.Count

                    'Now we can start checking the directory for changes                
                    Timer1.Start()

                End If

            Next

            'Hide 
            CutToolStripMenuItem.Visible = False

        End If

    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

        If Check_CopyMove() = "Move" And Clipboard.ContainsData(DataFormats.FileDrop) Then

            'Loop my Listviews
            Dim LVies = New System.Windows.Forms.ListView() {Listview1, Listview2}
            For Each LV In LVies

                'If some Listview has item with Backcolor.InactiveBorder, then this is the our "Cut" location
                For Each item As ListViewItem In LV.Items

                    If item.BackColor = SystemColors.InactiveBorder Then

                        If Lview_ItemsCount = LV.Items.Count Then
                            Dim CurrentItem As String = item.Tag.ToString

                            'Do a refresh of currently viewed directory in Listview - I have 2 functions for this (Load_Directory,GetCurDir)
                            Load_Directory(LV, GetCurDir(LV))

                            'After new refresh is done we search for item that was Backcolor.InactiveBorder
                            For Each NewItem In LV.Items
                                If NewItem.tag = CurrentItem Then
                                   NewItem.backcolor = SystemColors.InactiveBorder
                                End If
                            Next

                        'If variable Lview_ItemsCount is greater than Listview.Items.Count this means that "Cut" item was removed from directory after Paste is done
                        ElseIf Lview_ItemsCount > LV.Items.Count Then
                            Lview_ItemsCount = 0
                            FileCollection.Clear()
                            Clipboard.Clear()
                            Timer1.Enabled = False
                        End If
                    End If
                Next
            Next

        'User could change Cut to Copy meanwhile, so we have to handle this too
        ElseIf Check_CopyMove() = "Copy" Or Check_CopyMove() = "" Then
            Lview_ItemsCount = 0
            Timer1.Enabled = False
        End If

    End Sub
So, basically what I do is constantly refreshing Listview to check If any item was removed. If It does, then Timer1 stops. Inherited double-buffered Listview prevents any flickering of It while refreshing, so user doesn't basically see an difference...

I haven't tested my code fully, but 1 thing is for sure - while refreshing Listview app uses more memory that I would desire. And I will probably experience some other issues here, although code looks like It's working.

So my question is: IS THERE ANY BETTER/SHORTER WAY TO DETECT PASTE AFTER CUT TO CLEAR CLIPBOARD, SAME AS WINDOWS EXPLORER DOES ?