locked
Trying to swap/rename icons, but Dispose breaks link? RRS feed

  • Question

  • I'm trying to swap & rename two displayed icons.

    So I backup the first icon to a variable, Dispose of the original so I can rename the file, do the swap, then later try to copy the Backup to the second. Problem is, Disposing of the original appears to also wipe out the Backup:

    I'm not quite sure what's happening or how to resolve the issue. Any help is appreciated.

    TIA

    Wednesday, July 10, 2019 11:37 PM

Answers

  • Hi

    I think you will likely dismiss this reply as being of no use. You will likely not want to entertain a major re-write.

    However, here is what I have come up with.

    Set up a Class for you data. Use a List to store instances - this would simplify many of the procedures you would need during the rest of the code. A Class deals with each item as an entity and (for example), keeps the Description together with the Image throughout the application. Although not shown, the collection of the Class instances can be saved/loaded as a group.

    Use a FileStream to fetch the Images instead of FileSystem which would eliminate all the 'file in use' issues.

    Use List(Of .....) instead of arrays which would  simplify things dramatically.

    A simple example:

    Option Strict On
    Option Explicit On
    Public Class Form1
    	Dim thumbnails As New List(Of Item)
    	Dim mydir As String = "C:\Users\lesha\Desktop\New folder"
    	Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    		Dim p As List(Of String) = IO.Directory.GetFiles(mydir, "*.png").ToList
    		For Each s As String In p
    			Dim ni As New Item
    			With ni
    				.Path = s
    				.Desc = "This is a Description - could be any string"
    				.Im = GetImage(s)
    				thumbnails.Add(ni)
    			End With
    		Next
    	End Sub
    	Function GetImage(s As String) As Image
    		Dim im As Image
    		Using fs As New IO.FileStream(s, IO.FileMode.Open, IO.FileAccess.Read)
    			im = Image.FromStream(fs)
    		End Using
    		Return im
    	End Function
    	Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    		' here, any file operations can be
    		' performed without any issues.
    
    	End Sub
    	Class Item
    		Property Path As String
    		Property Im As Image
    		Property Desc As String
    	End Class
    End Class
    


    Regards Les, Livingston, Scotland

    Thursday, July 11, 2019 11:14 AM

All replies

  • Hi

    Do you expect your readers to work from an Image? Maybe retype the code themselves? Perhaps get annoyed at you? Possibly ignore your post!

    That is what the Code Block tool in the toolbar is for ..............


    Regards Les, Livingston, Scotland

    Wednesday, July 10, 2019 11:55 PM
  • Do you expect your readers to work from an Image?

    Here's the text, but it probably won't help much. It's a tiny block from a much larger program:

    ' intCheck1 is position/filenumber of first checked icon.
    ' intCheck2 is position/filenumber of second checked icon.

    ' Before we can rename the pngs, we must unload them first. thumbswap = thumbnails(intCheck1).Image    ' "thumbswap" is type "Image". Save copy. descswap = descriptions(intCheck1).Text ' Backup first description before overwriting. thumbnails(intCheck1).Image.Dispose() ' First unlink icon1 image. Must dispose first. thumbnails(intCheck1).Image = picBlank.Image ' Next, remove from screen. ' Rename first Item to "00". For Each myFile In Directory.GetFiles(mydir, strCategory & Format(intCheck1 + 1, "00") & ".*") ' Find multiple files with same name but diff ext. My.Computer.FileSystem.RenameFile(myFile, strCategory & "00" & Mid(myFile, InStrRev(myFile, "."))) ' Rename first checked items to index "00" & extension. Next ' Copy Icon2 & Descriptions2 to Slot1. thumbnails(intCheck1).Image = thumbnails(intCheck2).Image ' Copy second icon over first. descriptions(intCheck1).Text = descriptions(intCheck2).Text ' Backup second description. ' Must unload second icon before we can rename it. thumbnails(intCheck2).Image.Dispose() ' First unlink icon1 image. Must dispose first. thumbnails(intCheck2).Image = picBlank.Image ' Next, remove from screen. ' Rename intCheck2 items to intCheck1. For Each myFile In Directory.GetFiles(mydir, strCategory & Format(intCheck2 + 1, "00.*")) ' Renumber "00" files to intCheck2 My.Computer.FileSystem.RenameFile(myFile, strCategory & Format(intCheck1 + 1, "00") & Mid(myFile, InStrRev(myFile, "."))) Next ' Rename "00" items to intCheck2. For Each myFile In Directory.GetFiles(mydir, strCategory & "00.*") ' Renumber "00" files to intCheck2 My.Computer.FileSystem.RenameFile(myFile, strCategory & Format(intCheck2 + 1, "00") & Mid(myFile, InStrRev(myFile, "."))) Next ' Restore backed-up Item1 to Item2. thumbnails(intCheck2).Image = thumbswap descriptions(intCheck2).Text = descswap


    Let me know if you can resolve the issue. TIA.



    Thursday, July 11, 2019 12:16 AM
  • Hi

    I think you will likely dismiss this reply as being of no use. You will likely not want to entertain a major re-write.

    However, here is what I have come up with.

    Set up a Class for you data. Use a List to store instances - this would simplify many of the procedures you would need during the rest of the code. A Class deals with each item as an entity and (for example), keeps the Description together with the Image throughout the application. Although not shown, the collection of the Class instances can be saved/loaded as a group.

    Use a FileStream to fetch the Images instead of FileSystem which would eliminate all the 'file in use' issues.

    Use List(Of .....) instead of arrays which would  simplify things dramatically.

    A simple example:

    Option Strict On
    Option Explicit On
    Public Class Form1
    	Dim thumbnails As New List(Of Item)
    	Dim mydir As String = "C:\Users\lesha\Desktop\New folder"
    	Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    		Dim p As List(Of String) = IO.Directory.GetFiles(mydir, "*.png").ToList
    		For Each s As String In p
    			Dim ni As New Item
    			With ni
    				.Path = s
    				.Desc = "This is a Description - could be any string"
    				.Im = GetImage(s)
    				thumbnails.Add(ni)
    			End With
    		Next
    	End Sub
    	Function GetImage(s As String) As Image
    		Dim im As Image
    		Using fs As New IO.FileStream(s, IO.FileMode.Open, IO.FileAccess.Read)
    			im = Image.FromStream(fs)
    		End Using
    		Return im
    	End Function
    	Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    		' here, any file operations can be
    		' performed without any issues.
    
    	End Sub
    	Class Item
    		Property Path As String
    		Property Im As Image
    		Property Desc As String
    	End Class
    End Class
    


    Regards Les, Livingston, Scotland

    Thursday, July 11, 2019 11:14 AM
  • Use a List to store instances.


    This is a good idea. I don't know if copying the images to a (hidden) ListView will retain the images after disposing the source, but this is a method I hadn't considered.

    What I ended up doing instead was a bit more crude. It dawned on me that I didn't really need to store the loaded icon during the swap procedure. So instead, I dispose of it without ever copying it, perform the swap/file-rename, then when done, reload the images directly off the drive using:

    thumbnails(intCheck2).Image = Image.FromFile(strIconPath & "Save\" & strCategory & Format(intCheck2 + 1, "00") & ".png")

    Not very elegant, but works without a major rewrite. :)


    Thursday, July 11, 2019 11:57 AM
  • Hi

    There is something strange about wanting to keep an Image in a hidden ListView. If the Image is not to be visible to the User, then why have it anywhere - instead, just store the path and if/when needed to view, fetch it and display it.

    BTW: a hidden Listview is no different in principle to a plain ordinary List(Of ......). Indeed, a List(Of ....) is much easier to work with.

    The Function I posted above is a convienient way to deal with storing Image paths - access when needed.

    BTW: a Class similar to the one I posted above can have as many Properties as needed and can dramatically improve coding. For example, it doesn't need the Image itself, it would have the path and that is all that is needed to retrieve/edit/rename/delete etc.


    Regards Les, Livingston, Scotland


    • Edited by leshay Thursday, July 11, 2019 12:09 PM
    Thursday, July 11, 2019 12:09 PM