Autor Beitrag
McFlayr
Hält's aus hier
Beiträge: 13



BeitragVerfasst: Mi 14.09.16 14:30 
Hallo Community,

da mir hier letztens so gut geholfen wurde und ich nach dem durchforsten anderer Foren immer noch keine Lösung gefunden habe, hoffe ich hier auf etwas Hilfe.

Ich habe eine WindowsForms Anwendung, auf der Hauptform befindet sich ein Panel auf dem man zeichnen kann, außerdem lassen sich dort eigene Controls adden, diese wiederum lassen sich per Drag'n'Drop verschieben und skalieren. Die Controls auf dem Panel wurde von einer PictureBox abgeleitet.
Nun zum Problem: Ich möchte den Zustand des Panels, samt gezeichneten Inhalt und den Controls, die "geaddet" wurden, speichern und auch wieder laden können.
Ich habe dies mit Serilisation versucht. Mit einer einfachen eigenen Klassen hat dies auch problemlos funktioniert, diese Klasse dann abgeleitet von einem Label funtioniert wiederum nicht.
Andere Ansätze, wie die Properties auslesen und in einer Textdatei speichern und diese dann wieder einlesen, hat bisher auch noch nicht zum gewünschten erfolg geführt.

Hat jemand eine passende Lösung beziehungsweise einen Lösungsansatz ?


Vielen Dank im Voraus.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 14.09.16 15:15 
Zitat:
Ich habe eine WindowsForms Anwendung, auf der Hauptform befindet sich ein Panel auf dem man zeichnen kann, außerdem lassen sich dort eigene Controls adden, diese wiederum lassen sich per Drag'n'Drop verschieben und skalieren. Die Controls auf dem Panel wurde von einer PictureBox abgeleitet.


Ich hab jetzt auf die schnelle keine gute Idee aber nur eine Frage. Du hast nicht den Winforms Designer in deiner Anwendung gehostet sondern das soweit selbst gemacht? Und es hat auch soweit keine Verwandschaft mit dem was der Winforms Designer tut so das man den hier nicht einfach verwenden könnte?
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 14.09.16 15:45 
user profile iconMcFlayr hat folgendes geschrieben Zum zitierten Posting springen:
Andere Ansätze, wie die Properties auslesen und in einer Textdatei speichern und diese dann wieder einlesen, hat bisher auch noch nicht zum gewünschten erfolg geführt.

Was genau hat denn daran nicht funktioniert? Denn dies ist m.E. der einzig vernünftige Ansatz, also eigene Klassen erstellen, welche dann mit den entsprechenden Control-Eigenschaften synchronisiert werden.
McFlayr Threadstarter
Hält's aus hier
Beiträge: 13



BeitragVerfasst: Mi 14.09.16 16:00 
Zitat:
Ich hab jetzt auf die schnelle keine gute Idee aber nur eine Frage. Du hast nicht den Winforms Designer in deiner Anwendung gehostet sondern das soweit selbst gemacht? Und es hat auch soweit keine Verwandschaft mit dem was der Winforms Designer tut so das man den hier nicht einfach verwenden könnte?


Ich habe schon alles mit dem WinForms Designer gemacht. Lediglich das Panel, das ich dank deiner Hilfe erstellen konnte, und die Controls die darauf liegen sind selbst erstellt.


Zitat:
Was genau hat denn daran nicht funktioniert? Denn dies ist m.E. der einzig vernünftige Ansatz, also eigene Klassen erstellen, welche dann mit den entsprechenden Control-Eigenschaften synchronisiert werden.


Das es nicht funktioniert war wohl meiner Geduld geschuldet. :)
Ich dachte es muss doch einen eleganteren Weg geben diese vorhaben umzusetzen.
Vielleicht versuche ich es doch auf diesem Weg, empfiehlt es sich da eine INI-Datei zu nehmen oder doch eher eine Textdatei oder csv?

Ist es denn so abwegig den Zustand eines Controls zu speichern? Ich kann doch nicht der einzige sein der so etwas vorhat?
McFlayr Threadstarter
Hält's aus hier
Beiträge: 13



BeitragVerfasst: Do 15.09.16 09:49 
Guten Morgen.

Ich versuche das jetzt mal anhand eines einfachen Labels.
Ich habe jetzt alle Eigenschaften eines Labels in eines Textdatei gespeichert.
Als Trennzeichen habe ich "%" verwendet, somit ergibt sich folgendes Format in der Textdatei:

Eigenschaft1%Value
Eigenschaft2%Value

Der Code zum erstellen der Textdatei sieht folgendermaßen aus:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
Type t = label1.GetType();
PropertyInfo[] pi = t.GetProperties();
using (StreamWriter sw = new StreamWriter(Application.StartupPath + @"\eigenschaften.txt"))
{
    foreach (PropertyInfo prop in pi)
    {
        sw.WriteLine(prop.Name + "%" + prop.GetValue(label1, null));
    }
}


Nun stellt sich mir die Frage ist es möglich, wenn ich ein neues Label anlege, ihm die Eigenschaften aus der Textdatei zu zuweisen, ählich wie beim auslesen der Eigenschaften?
Beispielsweise mit einer foreach-Schleife durch die Eigenschaften gehen und die Werte aus der .txt zuordnen.
Mit PropertyInfo war es mir nicht möglich, den Eigenschaften, einen Wert zu zuweisen.
Gibt es da eine Möglichkeit?

Vielen Dank schon mal
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 15.09.16 10:46 
PropertyInfo.GetValue hast du offensichtlich gefunden genauso gibt es auch ein PropertyInfo.SetValue.

Du wirst aber vermutlich über Reihenfolge Probleme beim Setzen der Properties stossen. Die sind nicht alle unabhängig voneinander bzw. sind nicht immer sinnvoll setzbar.
Was mir so einfällt sind Abhängigkeiten zwischen Location und Width/Height, Size und MinSize/MaxSize, Visible/Enable zwischen Control und seinen ChildControls, setzen von Visible vor oder nach dem anzeigen des Controls etc.

Nicht alle davon werden Probleme machen, es sind aber auch nur die die mir gerade eingefallen sind. Gefühlt wäre es wohl besser sich auf eine sinnvolle Anzahl Properties der Controls zu beschränken und die in einer fixen Reihenfolge zu lesen und zu schreiben. Vermutlich willst du ja nicht jedes Control und alle Properties dieser Controls zulassen. Dann kannst du wirklich besser geich den Winformsdesigner benutzen und den generierten DesignerCode verwenden.
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: Do 15.09.16 12:18 
Bitte nicht pauschal Properties speichern und dann wieder schreiben. Das wird nicht funktionieren, die Gründe hat Ralf schon genannt und darüber hinaus ist das eine riesen Fehlerquelle.
Auch binäre Serialisierung würde nicht funktionieren, weil alle verwendeten Klassen das Serializable-Attribut haben müssten.


Wenn Du einen derart komplexen Designer haben willst wie der WinForms-Designer es ist, dann solltest Du den auch nutzen. (Ich hab keine Ahnung wie, aber Ralf wird wissen was er sagt :D)


Wenn Du dir aber einen Designer für z.B. UML-Diagramme bauen willst und für die Controls eine feste Zahl von Eigenschaften hast, dann solltest Du die direkt setzen, nicht per Reflection.
Dadurch wirst Du auch flexibler, denn wenn Du nur die Liste der Eigenschaften per Reflection liest/schreibst und dann wird eine Eigenschaft durch eine oder mehrere Andere ersetzt, sind alle bisher gespeicherten Stände inkompatibel und mal eben ändern geht dann auch nicht.

Außerdem solltest Du XML nehmen, das ist flexibler als CSV und .NET hat gleich mehrere Möglichkeiten zum XML Serialisieren, wo Du dich um so Geschichten wie Escapen nicht kümmern brauchst.
Das müsste sich mit dem XMLSerializer auch ziemlich leicht lösen lassen, wenn Du IXmlSerializable implementierst und mit dem XmlRootAttribute den Namen für das Element setzt.