Domanda

Nel mio ListView mostro miniature delle piccole immagini in una determinata cartella. ha installato il listview nel seguente modo:

var imageList = new ImageList();
foreach (var fileInfo in dir.GetFiles())
{
    try
    {
        var image = Image.FromFile(fileInfo.FullName);
        imageList.Images.Add(image);
    }
    catch
    {
        Console.WriteLine("error");
    }
}

listView.View = View.LargeIcon;
imageList.ImageSize = new Size(64, 64);
listView.LargeImageList = imageList;

for (int j = 0; j < imageList.Images.Count; j++)
{
    var item = new ListViewItem {ImageIndex = j, Text = "blabla"};
    listView.Items.Add(item);
}

L'utente può fare clic destro su un'immagine nella listview per rimuoverlo. Tolgo dal listview e poi voglio cancellare questa immagine dalla cartella. Ora ho l'errore che il file è in uso. Naturalmente questo è logico in quanto l'imagelist utilizza il file.

Ho cercato di rimuovere prima l'immagine dal imagelist, ma io continuo a avere il blocco di file.

Qualcuno può dirmi che cosa sto facendo male?

Grazie!

È stato utile?

Soluzione

È necessario caricare il file in un MemoryStream, in questo modo:

var image = Image.FromStream(new MemoryStream(File.ReadAllBytes(fileInfo.FullName)));

In questo modo, il file verrà letto solo una volta, e non resterà bloccato.

Modifica

che si desidera caricare le immagini in un ImageList.
Dal momento che l'ImageList crea copie delle sue immagini, si dovrebbe semplicemente smaltire gli originali subito, in questo modo:

using (var image = Image.FromFile(fileInfo.FullName))
    imageList.Images.Add(image);

Altri suggerimenti

L'immagine dovrà essere smaltito prima che possa sbloccare il file. Prova a chiamare Dispose sull'oggetto immagine dopo aver rimosso dall'elenco delle immagini.

Fino a quando si dispone di un riferimento all'oggetto immagine e il GC non ha raccolto che, manterrà il blocco. Chiamando Dispose dovrebbe costringerlo a rinunciare al suo manico e causare il file per essere sbloccato.

È inoltre necessario fare in modo che l'applicazione non ha CopyHandle o comunque ottenere un secondo riferimento alla risorsa immagine prima di fare questo.

Usa GetThumbnailImage e immagine poi dispose:

var image = Image.FromFile(fileN);

Image imgThumb = image.GetThumbnailImage(100, 100, null, new IntPtr());

imageList1.Images.Add(imgThumb);

image.Dispose();

listView1.LargeImageList = imageList1;

Ora è possibile eliminare il file:

File.Delete(FileN);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top