Hallo,
vielleicht kann mir jemand helfen zu WPF MVVM
Ich habe eine Klasse (Bilder) erstellt, dazu eine ObservableCollection in einem ViewModel. Diese Speichert Informationen zu Bildern die auf dem Laufwerk liegen.
String Pfad {get; set;}
String Bildname {get; set;}
usw.
In der Klasse wird der Pfad zu den Bildern gespeichert z.B. Ablageort = C:// Bilder/meinBild.jpg
Die ObservableCollection wird dann in XAML (View) als Liste angezeigt.
<Image Source="{Binding Klasse.Bild}"
Das klappt auch alles
Die Liste mit den Bildinformationen sicher ich dann in einer xml Datei.
Wenn ich aber nun versuche das Bild zu löschen, dann bekomme ich die Fehlermeldung, dass das Bild noch verwendet wird. Ich bekomme es einfach nicht hin, das Bild als Kopie zu öffnen, damit der Zugriff auf die Bilddatei möglich ist. Der Bildordner soll nicht als Ressource im Projekt eingebunden werden.
Mein Problem ist bei MVVM.... wie kann ich im ViewModel das Bild als Image holen und an die View übergeben?
Danke für eure Hilfe
Gruß
ASommer
Das hat mit MVVM nichts zutun, sondern wie Resourcen in .NET verwaltet werden bzw wie Betriebssysteme funktionieren. Das kannst Du auch alles in der Doku nachlesen:
Willst Du das Bild löschen, während Du es anzeigst, dann musst Du das Bild zuerst in den RAM laden, zB. mit Hilfe eines Memory Streams.
PS: Du suchst nach Hilfe, daher beachte in Zukunft bitte [Hinweis] Wie poste ich richtig?
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Verstanden soweit.
Leider fehlt mir das wissen wie ich das mit dem Memory Stream mache.
Wo mache ich das am besten im View , im ViewModel oder XAML?
Dann musst Dir das Wissen aneignen, zB. weil andere Leute schon das Problem hatten 🙂Google Suche nach "c# image memorystream"
Du kannst es alternativ auch direkt als Byte Array lesen, und dann ImageSource nutzen.
Steht alles auch in der Doku. Um das Lesen kommst leider nicht drum herum 🙂Google Suche nach "wpf image byte array"
Die Umsetzung wäre im ViewModel, siehe auch [Artikel] MVVM und DataBinding für die Verantwortlichkeiten.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Ich habe mir erstmal damit beholfen.
Das Bild wird dann in xml gespeichert und wieder gelesen somit muss ich das Original nicht löschen.
Muss jetzt nur noch schauen, dass ich die Bilder verkleinert bekomme, damit die xml nicht zu groß wird.
System.IO.File.ReadAllBytes(filePath);
Mit dem lesen... konnte ich ein wenig mehr darüber erfahren, aber so richtig schlau bin ich daraus noch nicht geworden.
XML für Binärdaten? Hört sich nich gerade nach einer schlauen Lösung an.
Willst vielleicht einfach mal erzählen, was Du überhaupt machen willst und was die Anforderungen sind?
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Ganz Trivial eigentlich.
Beispiel: Eine ObservableCollection<Personen>
Diese ObservableCollection will ich als XML auf der Festplatte speichern, damit beim nächsten Programmaufruf die Daten wieder da sind.
Zu jeder Person gibt es ein Bild. Im ersten Ansatz hatte ich einen Ordner angelegt und dort eine Kopie des Bildes gespeichert wenn man eine neues Bild/Person hinzufügt.
Wenn ich aber aus der ObservableCollection den Eintrag lösche... war der Zugriff (von meinem Programm) auf dem Bild noch da, somit konnte ich das Bild nicht löschen.
Mit der jetzigen Methode, habe ich das Bild der Person in der XML der ObservableCollection gespeichert. Somit brauche ich keinen neunen Ordner wo die Bilder rein kommen.
Ob das der richtige weg ist weiß ich nicht... bin Newbie in der Sache was WPF und C# angeht.
Dann hast Du Dir jetzt quasi mehr Arbeit gemacht und nicht die Ursache sondern nur das Sympton gelöst - aber neue Steine in Weg gelegt.
Lade Deine Bilder in den Speicher und binde den Speicher an Deine View - nicht das Bild direkt.
Bei den Personen speicherst Du nur den Pfad zum Bild ab - mehr nicht. Würde man so in "echten Datenbank" genau so machen, weil Binärdaten in der Masse absolut nichts in relationalen Datenbanken zu suchen haben.
Hättest also mit ~5 Zeilen Code einfach lösen können (via MemoryStream oder Byte-Array, wie oben genannt).
Das wäre auch die technisch bessere Variante gewesen als Binärdaten in einer XML.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo Abt,
danke für deine Hilfe. Genauso will ich es und wollte ich es auch machen. Aber das Problem war darin, dass ich es nicht hinbekomme das Bild darzustellen.
Bin fleißig dran das Problem zu beheben, aber ein bisschen fehlt mir noch alles zu kapieren.
~5 Zeilen Code einfach lösen können (via MemoryStream oder Byte-Array, wie oben genannt).
Hättest du vielleicht ein Beispiel von dem MemoryStream?
Danke für deine Tipps.
Gruß
ASommer
Ein Bild in den Speicher laden
using (MemoryStream ms = new MemoryStream())
using (FileStream file = new FileStream("file.bin", FileMode.Open, FileAccess.Read)) {
byte[] bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
ms.Write(bytes, 0, (int)file.Length);
}
Im View Model eine Eigenschaft vom Typ byte[] anlegen
private byte[] userImage;
public byte[] UserImage
{
get { return userImage; }
set
{
if (value != userImage)
{
userImage = value;
OnPropertyChanged("UserImage");
}
}
}
Und im Xaml darauf binden
<Image Source="{Binding UserImage}"/>
Alles ungetestet! Das Byte-Array muss noch mit der Eigenschaft UserImage verbunden werden.
Hättest du vielleicht ein Beispiel von dem MemoryStream?
Wieso schaust nicht einfach in die Suchtreffer aus meinem ersten Beitrag? Da steht alles mit Erklärung und Co.
Oder einfach in die Dokumentation schauen.
@Caveman das sieht nach .NET 3.5 Code oder früher aus.
Seit .NET 4 kann man einfach CopyTo verwenden
fileStream.CopyTo(memoryStream);
Den Magic String im Property Event braucht man mittlerweile auch nicht mehr; so ist die potentielle Fehlerquelle auch eliminiert.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
@Caveman das sieht nach .NET 3.5 Code oder früher aus.
Seit .NET 4 kann man einfach CopyTo verwenden
Ich habe in dem Fall einfach nur stur gegoogelt und die erstbesten Beispiele von StackOverflow kopiert.
Dass mit CopyTo habe ich gelesen, wollte es aber nicht posten, weil es dann keine 5 Zeilen Code geworden wären 😉
Deswegen hatte ich auch geschrieben, dass ich das selber nicht probiert hatte.
weil es dann keine 5 Zeilen Code geworden wären 😉
using...
using...
{
CopyTo
}
🙂
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code