Results 1 to 2 of 2

Thread: [RESOLVED] Detect Paste file - clear Clipboard after file Cut/Paste operation

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2016
    Location
    Slovenia
    Posts
    575

    Resolved [RESOLVED] Detect Paste file - clear Clipboard after file Cut/Paste operation

    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 ?

  2. #2

    Thread Starter
    Fanatic Member
    Join Date
    Nov 2016
    Location
    Slovenia
    Posts
    575

    Re: Detect Paste file - clear Clipboard after file Cut/Paste operation

    To answer myself...Yes there is a better way, with FileSystemWatcher to monitor all your changes in directories and then do whatever you need (clear clipboard, refresh Listview etc.). It doesn't quite shorten code for all Cut/Copy/Paste/Drag/Drop operations but works better without wiping out a lot of memory while proccesing. Though my app uses only 2 large directories in Listviews so monitoring with FileSystemWatcher is not so hard. If I had Listviews where I could navigate throughout all my drives that monitoring would be probably more difficult. It's just too bad that tracking end of Cut operation is not available yet, It would make things much easier.

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