2012-12-05 18 views
5

Ich habe Bilddateien (PNG) von meinem GridView als Teil seiner DataTemplate verwendet. Wenn ich versuche, eine bestimmte Objektzeile in meiner GridView zu löschen, würde ich auch die zugehörige Bilddatei für diese Zeile löschen. Die Bilder sind für jedes Element auf der Liste unterschiedlich.Zugriff verweigert beim Löschen von Bilddateien zuvor in DataTemplate in WinRT verwendet

ich diesen Code bin mit der Bilddatei

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

Die Bilddatei auf dem Gridview gerendert unter der Datatemplate des Gridview ist zu löschen. Also habe ich in jedem Objektmodell in meiner Liste eine öffentliche Eigenschaft, die eine ImageSource für meine DataTemplate zurückgibt.

Ich rufe meine Löschprozedur direkt nach dem Löschen der Objektzeile aus der Liste und nachdem die GridView von den neuen Listelementen aktualisiert wurde.

Obwohl die Liste das Objekt (das das Bild verbraucht) nicht mehr enthält, löst die Anwendung die Ausnahme Zugriff verweigert aus, wenn ich versuche, die Datei zu löschen. Wenn ich während der Ausführung der App versuche, diese bestimmte Datei manuell zu löschen (über den Datei-Explorer), wird es mir auch nicht erlauben.

Ich habe versucht, alle nicht verwendeten Objekte in meiner App zu löschen, sogar die ItemSource der GridView auf null und die Liste auf null zu setzen, bevor ich das Bild lösche. Die Ausnahme bleibt bestehen.

Vielen Dank im Voraus.

Antwort

0

Der Trick besteht darin, ein Uri-Objekt zu verwenden, um das Bild zu laden (anstelle eines Zeichenketten-Dateinamens) und dann die EXAKT-gleiche Uri-Instanz zu verwenden, um die Datei zu löschen (natürlich nach dem Entfernen des Bildes von der UI). Hier ein Beispiel:

//Save the Uri as a member variable so you can get to it later 
private Uri uri; 

//Create the Uri 
uri = new Uri(OriginalImageFilename, UriKind.Absolute); 

//Load the image 
BitmapImage bitmapImage = new BitmapImage(uri); 
//This can also be done by binding a Image control's source property to the uri. 

//Delete the image (remember to use the same Uri instance) 
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(uri); 
await file.DeleteAsync(); 
+0

Dank @Kinect_dev, aber ich bekomme immer noch den Fehler, wenn ich Ihren Vorschlag ausprobiert. – King

0

Als Behelfslösung, i gelöscht nur die nicht verwendeten Bilder während der App-Start so, dass keine Prozesse es verwenden. Vielen Dank.

1

Eine Methode, die Sie versuchen können, ist das Laden des Bildes in ein Speicher-Steam, dann Erstellen eines BitmapImage Objekts aus diesem Stream, Sie können dann die Quelle Ihres Image Steuerelements auf dieses Bitmap-Bild festlegen.

Da Sie nicht die eigentliche Bild-Datei als Quelle des Bildes verwenden, können Sie es jederzeit leicht löschen können :)

1

Obwohl dies eine alte Frage ist, ich habe das Problem vor kurzem in einem UWP App gestoßen und tatsächlich geschafft, eine Lösung zu finden. Aber zuerst einige Hintergrundinformationen über das Problem:

Wenn Sie eine BitmapImage mit einem URI erstellen, enthält das erstellte URI-Objekt einen Verweis auf die Datei in Ihrem lokalen Speicher und hält es geöffnet, d. H. Nicht beschreibbar. Dies ist nur wahr, wenn die Bitmap gerade groß genug ist, um vollständig in das Image zu passen, typischerweise kleine oder mittelgroße Bitmaps. Wenn das Bitmap groß genug ist, verwendet WinRT automatisch eine heruntergesetzte Version, wenn es in einem Bild angezeigt wird. In diesem Fall enthält der URI KEINE Referenz auf die Originaldatei.

Nun zur eigentlichen Lösung:

Einstellung Image.Source auf null funktioniert den Trick hier nicht tun, da der URI noch am Leben ist (bis zum nächsten GC-Zyklus zumindest). Was für mich funktionierte, war, dass ich die Source auf die BitmapImage umwandelte, die sie ursprünglich war, und die UriSource auf Null einstellte.

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

Und ja, das ist dumm.