Hallo,
die genaue Bezeichnung des Themas fällt mir schwer. Anbei deshalb eine kurze Erklärung des Sachverhaltes
Vorhaben
Ich habe ein Gridview mit einem gebunden Template, das ein <Image> enthält. An das Gridview binde ich eine Liste von Objekten, woraufhin die einzelnen Einträge angezeigt werden (unter anderem auch das BitMap). -> Das funktioniert soweit auch.
public string ThumbnailPath
{
get{
return "ms-appdata:///local/thumbnails/" + this._id.toString() + "_thumb_0.png");
}
}
Nun habe ich die App nach hinten erweitert und möchte die Bilder bei einigen Elementen tauschen. Dazu suche ich mir die Quelle (in dem Fall eine PDF aus der ich das Bild rendere) und schreibe das Bild entsprechend auf dem DAtenträger an die passende Position. Es ergeben sich zwei mögliche Fälle
Fallunterscheidung
Möglichkeit 1 - Es existiert zu der PDF-Datei noch kein Bild. Die PDF wird geöffnet, dass Bild gerendert und anschließend im Verzeichnis gespeichert -> funktioniert
Möglichkeit 2 - Es existiert bereits ein Bild zur PDF, die PDF wird geöffnet, das Bild gerendert und beim Speichern erhalte ich eine "Unauthorized Access"-Exception.
Meine Vermutung
Wenn das Bitmap-Image in der Gridview angezeigt wird, entsteht eine Referenz auf die Datei, die mir nach hinten raus sagt, dass die DAtei nciht überschrieben (auch nicht gelöscht) werden kann.
Lösungsansatz
a) Ich habe versucht alle gebundenen Listen zu nullen bzw. auf eine leere Liste zurück zu setzen...Problem besteht weiterhin.
b) Ich habe versucht das Bild in ein IRandomAccessStream zu laden, um daraus ein Bitmap abzuleiten...der Code läuft durch, aber ich erhalte keine Anzeige der Bilder mehr
public string ThumbnailPath
{
get{
return this.CreateBitapFromFile();
}
}
public async Task<BitmapImage> CreateBitmapFromFile()
{
BitmapImage image = new BitmapImage();
StorageFolder thumbsFolder = await ApplicationData.Current.LocalFolder.getFolderAsync("Thumbnails");
StorageFile file = await thumbsFolder.getFileAsync(this._id.toString() + "_thumb_0.png");
using(IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read))
{
await image.SetSourceAsync(stream);
}
return image;
}
Hat jemand von euch eine Idee, wie ich die Bilder an das Gridview binden kann, ohne eine Referenz auf die Datei zu halten? Ich möchte erreichen, dass ich über die App die Bilder tauschen kann.
Vielen Dank für jede Art von Hilfe.
Da du den Stream ja freigibst sollte das doch eigentlich passen. Falls du dir unsicher bist, kannst du die Datei ja in einen MemoryStream schreiben und das mal testen.
ImageTools for Silverlight: http://imagetools.codeplex.com | http://www.silverdiagram.net | http://www.cleancodedeveloper.de b:::
Hallo und schon einmal Danke für deine Antwort.
Der Code läuft durch, wirft auch keine fehler...aber die variante mit dem IRandomAccessStream liefert mir kein Bild im Gridview. Das Image-Element bleibt leer, vergesse ich an der Stelle etwas oder muss ich auf etwas bestimmtes achten?
Hallo ChristophF,
ich würde die Datei in einen MemoryStream kopieren und diesen zum Laden verwenden, da die Datei dann nicht geöffnet bleibt.
Am einfachsten ist es die Datei als Stream zu öffnen und mit CopyTo in den MemoryStream zu kopieren.
Danach die Position des MemoryStreams wieder auf 0 setzen und dann zum Laden des Bildes vewenden (den danach FileStream natürlich mit Close oder Dispose schließen).
Grüße
spooky
Hallo,
laut Debugger komme ich entsprechend oft in die Methode zum Erstellen des Images aus dem IRandomAccessStream (ich habe 7 Bilder im Ordner, 7 mal springt er rein).
Kann es sein, dass etwas mit der Datenbindung zum Image-Element nicht Stimmt?
<Image Source="{Binding Path=ThumbnailPath, Mode=TwoWay, UpdateSourceTrigger=OnPropertyChanged" Strech="Uniform" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
Die Methoden im hintergrund bleiben die selben, wie schon oben genannt. Ich scheine gerade wirklich auf dem Schlauch zu stehen.
Danke schon im Voraus.
Also oben in dem Beispiel stimmt was nicht mit dem async und await.
was für mich funktioniert hat:
public sealed class NodeIconBitmapConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
INodeIcon icon = (INodeIcon)value;
BitmapImage bitmapImage = new BitmapImage();
icon.OpenAsStreamAsync().ContinueWith(stream =>
{
if (stream.Result != null)
{
CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
CoreDispatcherPriority.Normal,
() =>
{
bitmapImage.SetSourceAsync(stream.Result.AsRandomAccessStream()).Forget();
}).Forget();
}
});
return bitmapImage;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotSupportedException();
}
}
ImageTools for Silverlight: http://imagetools.codeplex.com | http://www.silverdiagram.net | http://www.cleancodedeveloper.de b:::
Hallo,
ich hab das Beispiel am Wochenende noch einmal getestet...verstehe aber nicht so richtig die Zusammenhänge in deinem Converter. Besteht die Möglichkeit, dass du das Binding im XAML noch mit auflistest und gegebenenfalls 2-3 Sätze zum Verständnis?
Vielen Dank!