Autor Beitrag
GURKE deluxe
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 91
Erhaltene Danke: 1

Win 7 Home Premium x64, Win XP Home Edition v2002
C# Microsoft Visual C# 2010 Express
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 690
Erhaltene Danke: 16


VS2015 Pro / C# & VB.Net
BeitragVerfasst: So 24.02.13 22:20 
user profile iconGURKE deluxe hat folgendes geschrieben Zum zitierten Posting springen:

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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 91
Erhaltene Danke: 1

Win 7 Home Premium x64, Win XP Home Edition v2002
C# Microsoft Visual C# 2010 Express
BeitragVerfasst: So 24.02.13 22:27 
user profile iconChristoph1972 hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: 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. :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:
ausblenden C#-Quelltext
1:
2:
[XmlIgnore]
public string Eigenschaft { get; set; }

direkt über die Eigenschaft oder das Feld.


Beispiel:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 24.02.13 23:49 
Ok, stimmt, das ist ein Unterschied :D
Wahrscheinlich hat GURKE deluxe dann auch den Link erwischt ^^
GURKE deluxe Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 91
Erhaltene Danke: 1

Win 7 Home Premium x64, Win XP Home Edition v2002
C# Microsoft Visual C# 2010 Express
BeitragVerfasst: Mo 25.02.13 20:47 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
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.

user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
Das zu verwenden ist denkbar einfach, schreib einfach das:
ausblenden C#-Quelltext
1:
2:
[XmlIgnore]
public string Eigenschaft { get; set; }

direkt über die Eigenschaft oder das Feld.


Beispiel:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 91
Erhaltene Danke: 1

Win 7 Home Premium x64, Win XP Home Edition v2002
C# Microsoft Visual C# 2010 Express
BeitragVerfasst: Di 26.02.13 20:06 
Ich hab jetzt in der Klasse also folgenden Code:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4701
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 26.02.13 20:33 
Auf der Form dann denn IGrafikChanged Event abonnieren und dort dann aus den EventArgs das Image rausholen.

ausblenden 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(thisnew ImageChangedEventArgs() { Image = _iGrafik });
            }
        }
    }

    [XmlIgnore]
    public event EventHandler<ImageChangedEventArgs> IGrafikChanged;
}

public class ImageChangedEventArgs : EventArgs
{
    public Image Image { get; set; }
}