Entwickler-Ecke
IO, XML und Registry - Objekt einer Klasse abspeichern Objekte der Klasse auslassen
GURKE deluxe - So 24.02.13 21:00
Titel: Objekt einer Klasse abspeichern Objekte der Klasse auslassen
Hallo,
Ich habe eine Klasse, die aus verschiedenen Objekten besteht. Unter anderem aus einer PictureBox. Wenn ich diese per XML-Serializer serialisieren lassen möchte, so bekomme ich ein Fehler, dass das nicht funktioniert. Das muss es an sich eigentlich auch nicht, denn die Picturebox ist null. Sie wird erst gefüllt, nachdem die XML-Datei geladen wurde. Das heißt in der Datei stünde theoretisch einfach nur: <pbKarte />
Nun, obwohl das Objekt leer ist, möchte er die nicht laden/speichern. Jetzt gibt es die Möglichkeit, eine 2. identische Klasse zu schreiben, in der keine PictureBox ist. Beim Laden/Speichern muss ich dann lediglich die Klasse in die Hauptklasse konvertieren. Diese Methode finde ich allerdings sehr sehr unschön wie auch aufwendig und unnötig kompliziert.
Gibt es eine einfache Möglichkeit, ein Teil der Klasse vom Serialisieren auszuschließen?
Gruß
Julian
Christoph1972 - So 24.02.13 21:20
GURKE deluxe hat folgendes geschrieben : |
Gibt es eine einfache Möglichkeit, ein Teil der Klasse vom Serialisieren auszuschließen? |
Hi, ich würde den serialisierbaren Teil der Klasse in eine eigene Klasse auslagern und diese dann in der nicht serialiserten Klasse instanzieren, bzw. initialisiert an diese übergeben.
GURKE deluxe - So 24.02.13 21:27
Christoph1972 hat folgendes geschrieben : |
| Hi, ich würde den serialisierbaren Teil der Klasse in eine eigene Klasse auslagern und diese dann in der nicht serialiserten Klasse instanzieren, bzw. initialisiert an diese übergeben. |
Moin,
Erscheint mir logisch und simpel :D
Danke :)
Werde ich erstmal so machen. Allerdings habe ich gerade noch folgende Eigenschaft gefunden: XmlIgnore
Nun hilft mir die Hilfe nicht so direkt, bzw. das Beispiel wirkt ziemlich komplex. Ist dieses XmlIgnore denn dazu geeignet, für das was ich vorhabe?
Ralf Jansen - So 24.02.13 21:58
| Zitat: |
| Ich habe eine Klasse, die aus verschiedenen Objekten besteht. Unter anderem aus einer PictureBox. |
Visuelle Controls sind grundsätzlich nicht serialisierbar das macht auch keinen Sinn. Das einzige in der Picturebox was Sinn macht zu serialisieren wäre das enthaltene Bild.
Warum sollte man Handles, Margins, Padding etc.serialisieren? Und das Control hat natürlich noch Verweise auf seinen Parent der wiederum Verweise auf andere Controls hat. Letztlich würdest du also deine gesamte UI serialisieren. Ich weiß nicht genau was du da hast aber eine Klasse die zum serialisieren gedacht ist und einen Verweis auf ein Control hat hört sich nach einem größeren Design Fehler an. Überlege das nochmal grundsätzlich.
Ansonsten wenn du wieder aller Erwartung den Verweis in deiner Klasse brauchst markiere die Property mit dem
XmlIgnore [
http://msdn.microsoft.com/de-de/library/system.xml.serialization.xmlignoreattribute.aspx] Attribut dann wird dieser Verweis beim serialisieren ignoriert.
Palladin007 - So 24.02.13 22:01
| Zitat: |
Allerdings habe ich gerade noch folgende Eigenschaft gefunden: XmlIgnore
Nun hilft mir die Hilfe nicht so direkt, bzw. das Beispiel wirkt ziemlich komplex. Ist dieses XmlIgnore denn dazu geeignet, für das was ich vorhabe? |
Das
XmlIgnoreAttribute [
http://msdn.microsoft.com/de-de/library/system.xml.serialization.xmlattributes.xmlignore.aspx]
(besserer Link [http://msdn.microsoft.com/de-de/library/system.xml.serialization.xmlignoreattribute.aspx] mit einfacherem Beispiel) wollte ich gerade nennen. :D
Das ist nämlich genau für sowas gedacht. Dieses Attribut kennzeichnet eine öffentliche Eigenschaft oder ein öffentliches Feld so, dass der XmlSerializer beim serialisieren des Objektes diese Eigenschaft ignoriert.
Also eigentlich genau das, was du haben willst ^^
Das zu verwenden ist denkbar einfach, schreib einfach das:
C#-Quelltext
1: 2:
| [XmlIgnore] public string Eigenschaft { get; set; } |
direkt über die Eigenschaft oder das Feld.
Beispiel:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| using System.Windows.Forms; using System.Xml.Serialization;
public class BeispielKlasse { public string Name { get; set; }
[XmlIgnore] public PictureBox pictureBox { get; set; } } |
Hier wird nun nur die Eigenschaft
Name serialisiert,
pictureBox wird dagegen ignoriert.
Edit:
Verdammt, da warst du wohl schneller, Ralf ^^
Nagut, dann hat er noch ein kleines Beispiel dabei, weil das in der Dokumentation finde ich auch etwas umständlich.
Ralf Jansen - So 24.02.13 22:46
| Zitat: |
| Nagut, dann hat er noch ein kleines Beispiel dabei, weil das in der Dokumentation finde ich auch etwas umständlich. |
Wenn du dir das Beispiel beim XmlIgnore Attribut ansiehst (mein Link) und nicht das bei der XmlIgnore Property der XmlAttributes Klasse (dein Link, vergriffen?) siehst du das das vollkommen harmlos ist ;)
Palladin007 - So 24.02.13 22:49
Ok, stimmt, das ist ein Unterschied :D
Wahrscheinlich hat GURKE deluxe dann auch den Link erwischt ^^
GURKE deluxe - Mo 25.02.13 19:47
Ralf Jansen hat folgendes geschrieben : |
| Ich weiß nicht genau was du da hast aber eine Klasse die zum serialisieren gedacht ist und einen Verweis auf ein Control hat hört sich nach einem größeren Design Fehler an. Überlege das nochmal grundsätzlich. |
Hallo Ralf,
Die Picturebox speichere ich dort ab, um auf diese leicht zugreifen zu können, um das Bild zu ändern. Dazu muss die Picturebox natürlich nicht abgespeichert werden.
Palladin007 hat folgendes geschrieben : |
Das zu verwenden ist denkbar einfach, schreib einfach das:
C#-Quelltext 1: 2:
| [XmlIgnore] public string Eigenschaft { get; set; } |
direkt über die Eigenschaft oder das Feld.
Beispiel:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| using System.Windows.Forms; using System.Xml.Serialization;
public class BeispielKlasse { public string Name { get; set; }
[XmlIgnore] public PictureBox pictureBox { get; set; } } | |
In der Tat, dass sieht einfacher aus :D Ich war auch auf der anderen Seite, in der weit weit mehr Code drin stand, denn ich für relativ überflüssig hielt... Funktioniert somit auf Anhieb. Danke!
Ralf Jansen - Mo 25.02.13 19:57
| Zitat: |
| Die Picturebox speichere ich dort ab, um auf diese leicht zugreifen zu können, um das Bild zu ändern |
Dann speichere trotzdem in deiner Klasse auch nur das Bild. Pack einen Event in die Property die das Bild enthält der geworfen wird wenn sich das Bild ändert. Auf der Form wo das Bild angezeigt werden soll registriere den Event und aktualisiere in diesem EventHandler die Picturebox. Voilá, saubere Trennung von Model und UI.
Den Event solltest du aber trotzdem mit dem XmlIgnore Attribut markieren.
Palladin007 - Mo 25.02.13 20:28
Wenn anderweitig aus einem Objekt über Umwege auf das entsprechende Image-Objekt zugegriffen werden kann, dann könnte man doch auch eine Eigenschaft oder eine Methode schreiben, die diesen Umweg beinhaltet. So machst du es dir noch einfacher, weil du nicht angeben musst, dass das Bild in dieser Instanz gespeichert werden soll, es wird sich einfach immer dort her geholt, wo es sowieso schon ist.
Eine Eigenschaft oder Methode würde ich dann aber auch nur schreiben, wenn es wirklich sinnvoll ist, auf den Sinn und Zusammenhang der Klasse bezogen.
GURKE deluxe - Di 26.02.13 19:06
Ich hab jetzt in der Klasse also folgenden Code:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| private Image _iGrafik; public Image iGrafik { get { return this._iGrafik; } set { this._iGrafik = value; } } |
Nun muss vermutlich noch Code in den Set-Bereich. Aber wie bekomme ich dort ein Event rein, welches auf die Form zugreifen kann, die hierarchisch über der Klasse liegt?
Ralf Jansen - Di 26.02.13 19:33
Auf der Form dann denn IGrafikChanged Event abonnieren und dort dann aus den EventArgs das Image rausholen.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| public class MeineLiebeKlasse { private Image _iGrafik; public Image IGrafik { get { return this._iGrafik; } set { if (value != _iGrafik) { this._iGrafik = value; if (IGrafikChanged != null) IGrafikChanged(this, new ImageChangedEventArgs() { Image = _iGrafik }); } } }
[XmlIgnore] public event EventHandler<ImageChangedEventArgs> IGrafikChanged; }
public class ImageChangedEventArgs : EventArgs { public Image Image { get; set; } } |
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!