Autor |
Beitrag |
GURKE deluxe
Beiträge: 91
Erhaltene Danke: 1
Win 7 Home Premium x64, Win XP Home Edition v2002
C# Microsoft Visual C# 2010 Express
|
Verfasst: So 24.02.13 22:00
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
Beiträge: 690
Erhaltene Danke: 16
VS2015 Pro / C# & VB.Net
|
Verfasst: So 24.02.13 22: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.
_________________ Gruß
Christoph
|
|
GURKE deluxe
Beiträge: 91
Erhaltene Danke: 1
Win 7 Home Premium x64, Win XP Home Edition v2002
C# Microsoft Visual C# 2010 Express
|
Verfasst: So 24.02.13 22: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
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
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: So 24.02.13 22: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 Attribut dann wird dieser Verweis beim serialisieren ignoriert.
|
|
Palladin007
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: So 24.02.13 23: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 (besserer Link mit einfacherem Beispiel) wollte ich gerade nennen.
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.
Zuletzt bearbeitet von Palladin007 am So 24.02.13 23:51, insgesamt 3-mal bearbeitet
Für diesen Beitrag haben gedankt: GURKE deluxe
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: So 24.02.13 23: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
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: So 24.02.13 23:49
Ok, stimmt, das ist ein Unterschied
Wahrscheinlich hat GURKE deluxe dann auch den Link erwischt ^^
|
|
GURKE deluxe
Beiträge: 91
Erhaltene Danke: 1
Win 7 Home Premium x64, Win XP Home Edition v2002
C# Microsoft Visual C# 2010 Express
|
Verfasst: Mo 25.02.13 20:47
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 25.02.13 20: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
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: Mo 25.02.13 21: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
Beiträge: 91
Erhaltene Danke: 1
Win 7 Home Premium x64, Win XP Home Edition v2002
C# Microsoft Visual C# 2010 Express
|
Verfasst: Di 26.02.13 20: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
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Di 26.02.13 20: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; } } |
|
|