Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access Denied when deleting image file previously used in DataTemplate in WinRT

I have image (PNG) files used by my GridView as part of its DataTemplate. If I try to delete a specific object row in my GridView, I would delete the related image file for that row as well. The images are different for every item on the list.

I'm using this code to delete the image file

StorageFile _file = await DataStore.GetFileAsync(filename);
await _file.DeleteAsync(StorageDeleteOption.Default);

The image file is rendered on the GridView under the GridView's DataTemplate. So in each object model in my List, I have a public property there that returns an ImageSource for my DataTemplate.

I'm calling my delete procedure right after i deleted the object row from the List and after the GridView has been refreshed of the new List items.

Even though the List does not contain the object (consuming the image) anymore, the app throws the Access is Denied exception if i try to delete the file. While the app is running, if i try to delete that particular file manually (through file explorer), it won't allow me too.

I tried clearing all unused objects in my app, even setting the GridView's ItemSource to null and the List to null before I delete the image. Still the exception persist.

Thanks in advance.

like image 572
King Avatar asked Dec 05 '12 07:12

King


2 Answers

One method you can try is to load the image into a memory steam, then create a BitmapImage object from that stream, you can then set the source of your Image control to that bitmap image.

Since you are not using the actual image file as the source of the image, you can easily delete it anytime :)

like image 185
Mark Avatar answered Nov 17 '22 00:11

Mark


Though this is an old question, I have encountered the problem recently in a UWP app and actually managed to find a solution. But first some background information about the problem:

When you create a BitmapImage with a URI, the created URI object holds a reference to the file in your local storage and keeps it open, i.e. non-writable. This btw is only true when the Bitmap is just big enough to fit into the Image entirely, typically small or medium sized Bitmaps. If the Bitmap happens to be big enough, WinRT automatically uses a downsampled version when it is displayed in an Image. In this case the URI does NOT hold a reference to the original file.

Now to the actual solution:

Setting Image.Source to null doesn't do the trick here, as the URI is still alive (until the next GC cycle at least). What DID work for me, was casting the Source to the BitmapImage it originally was and settings the UriSource to null.

var bitmapImage = image.Source as BitmapImage;
if (bitmapImage != null)
  bitmapImage.UriSource = null;

And yes, this IS stupid.

like image 29
Eugen Timm Avatar answered Nov 17 '22 00:11

Eugen Timm