Autor Beitrag
Jimmy123
Hält's aus hier
Beiträge: 8



BeitragVerfasst: So 25.09.16 17:41 
Hallo zusammen,

vielleicht kann mir ja hier jemand weiterhelfen...

Ich habe eine einfache "leere" Windows Form. Diese bekommt beim starten zwei Buttons...

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:
26:
27:
28:
29:
        private void Form1_Load(object sender, EventArgs e)
        {
            Button cmdNewTextbox = new Button();
            cmdNewTextbox.Location = new Point(1010);
            cmdNewTextbox.Size = new Size(10020);
            cmdNewTextbox.Text = "New Textbox";

            Button cmdSerialize = new Button();
            cmdSerialize.Location = new Point(12010);
            cmdSerialize.Size = new Size(10020);
            cmdSerialize.Text = "Save...";

            cmdNewTextbox.Click += new EventHandler(cmdNewTextbox_click);
            cmdSerialize.Click += new EventHandler(cmdSerialize_Click);

            this.Controls.Add(cmdNewTextbox);
            this.Controls.Add(cmdSerialize);
        }

        private void cmdNewTextbox_click(object sender, EventArgs e)
        {
            TextBox txtBox = new TextBox();
            txtBox.Location = new System.Drawing.Point(10, i);
            txtBox.Name = "txt" + txt.ToString();
            txtBox.Text = "";
            this.Controls.Add(txtBox);
            txt++;
            i = i + 20;   //gibt die Position nach unten an
        }

Nun möchte ich diese Form "serialisieren" , um danach wieder auf die Daten zuzugreifen. Bei festen Objekten ist das kein Problem.

Wie mache ich es in diesem Fall?

Vielen Dank für eure Antworten...

Viele Grüße

Jimmy

Moderiert von user profile iconTh69: Titel geändert ("C# Windows Form" entfernt).


Zuletzt bearbeitet von Jimmy123 am So 25.09.16 19:02, insgesamt 1-mal bearbeitet
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 25.09.16 18:54 
Kannst Du noch die C#-Tags um den Code setzen?
Macht das Lesen um einiges leichter.

Und ich würde nicht die Form serialisieren, sondern nur die Daten, die Du brauchst.
Also Position, Größe, Text, etc.
WinForms unterstützt DataBinding, also schreib für jedes Control eine Klasse, was die Infos beinhaltet, die Du anzeigen und serialisieren willst. Das entsprechende Control bindet sich an das Objekt von dieser Klasse und dieses Objekt von dieser Klasse kannst Du auch ohne große Hindernisse in irgendeiner beliebigen Art serialisieren.

Die Form selber ist ja nicht nur ein simples Objekt was ein paar Daten beinhaltet und fröhlich ein Bild auf den Desktop malt.
Da passiert im Hintergrund deutlich mehr, unter Anderem auch intesinve Arbeit mit der Windows-API.
Das kannst Du nicht so einfach serialisieren und wenn dann nur über Umwege und einer ganzen Menge Seiteneffekte.
Jimmy123 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: So 25.09.16 19:09 
Ich will ja auch nur den die Elemente (Textboxen mit Inhalt) serialisieren. Hab schon oft gelesen, dass man keine Form serialisieren soll. Muss auch nicht sein. Wie kann ich denn eine dynamische Klasse erstellen? Die Textboxen sollen in der Gr´öße und Position änderbar sein (kommt noch).

Der Gedanke ging dahin:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
            foreach (var controls in this.Controls)
            {
                if(controls.GetType() == typeof(TextBox))
                {
                    //Serialisiere mich....
                }
            }
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 25.09.16 19:29 
Wozu eine dynamische Klasse?

Ich würde z.B. sowas machen:

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 abstract class ControlData
{
    public Point Location { get; set; }
    public Size Size { get; set; }

    public Control CreateControl()
    {
        var control = CreateControlInternal();
        control.Location = Location;
        control.Size = Size;
        return control;
    }
    protected abstract Control CreateControlInternal();
}
public class TextBoxData : ControlData
{
    public string Text { get; set; }

    protected override Control CreateControlInternal()
    {
        var textBox = new TextBox();
        textBox.Teyt = Text;
        return textBox;
    }
}


Vergiss nicht INotifyPropertyChanged zu implementieren, sonst funktioniert das DataBinding nicht.
Auch die Benennung könnte besser sein, aber ist ja nur ein Beispiel ^^


Am Ende hast Du dann eine Liste vom ControlData-Objekten.
Da läufst Du dann durch und für jedes Objekt erstellst Du das passende Control.
Z.B.:

ausblenden C#-Quelltext
1:
2:
foreach (var controlData in _myControlDataList)
    Controls.Add(controlData.CreateControl());


Soll serialisiert werden, dann serialisierst Du die _myControlDataList.
Soll deserialisiert werden, leerst Du die Controls, deserialisierst die _myControlDataList und lässt die Schleife zum erstellen der Controls wieder durch laufen.

Die Klassen-Beispiele oben sind so simpel gehalten, dass Du da auch den XmlSerializer verwenden kannst.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 25.09.16 20:04 
Nette Idee wenn du bei _myControlDataList an eine List<ControlData> denkst wird das aber etwas problematisch werden. Da wirst du zumindest dem XmlSerializer alle bekannte Ableitungen von ControlData (wie TextBoxData) bekannt machen müssen.
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 25.09.16 20:54 
Stimmt, der XmlSerializer hat ja diese Schwäche ...

Alternativ kann das aber auch eine Ableitung von List sein, die dann IXmlSerializable implementiert und den entsprechenden Typ darin zuordnet.
Man könnte ja z.B. statisch per Reflection auslesen lassen, welche Klassen direkt oder indirekt von ControlData ableiten.
Nicht unbedingt der schönste Weg, aber einfach, ohne viel Aufwand und man muss nicht jeden neuen Typ nochmal extra bekannt machen.
Jimmy123 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mo 26.09.16 07:10 
Guten Morgen zusammen,

ich werde es heute Abend nach der "Arbeit" mal ausprobieren. So ganz verstehe ich es noch nicht, da ich immer mit statischen Objekten gearbeitet habe, werd mich aber durchfuchsen.

Vielen Dank schon mal für eute Mühen...
Jimmy123 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mi 28.09.16 04:24 
Also irgendwie bekomme ich es nicht hin. Ist jetzt aber auch nicht weiter schlimm. Habs jetzt doch wieder statisch gemacht. Tut seinen Zweck...

Danke nochmal für eure Mühen...
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: Mi 28.09.16 08:37 
Zitat:
irgendwie bekomme ich es nicht hin


Heißt? :D


Statisch mag zwar seinen Zweck erfüllen, ist aber fast immer der schlechteste Weg, den Du wählen kannst :D
Wobei ich nicht einmal verstehe, wie man etwas dynamisches statisch machen soll O.o