List<OwnClass> als Property erzeugt ungültige ResX-Datei

  • C#
  • .NET (FX) 1.0–2.0

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von TRiViUM.

    List<OwnClass> als Property erzeugt ungültige ResX-Datei

    Guten Morgen liebe Community,

    =============================
    LÖSUNG:
    Die Property nicht vom Typ List<OwnClass> deklarieren, sondern eine neue Klasse OwnClassCollection:Collection<OwnClass> anlegen und die Property vom Typ OwnClassCollection anlegen :)
    =============================

    ich bin soeben auf ein Problem gestoßen, dessen Ursache ich mir noch nicht so ganz erklären kann.
    Mein Vorhaben war, Eine Liste (von einer eigenen Klasse) als Property bereit zu stellen.

    Hier die eigene Klasse:

    C#-Quellcode

    1. using System;
    2. using System.Drawing;
    3. namespace Control_Sandbox.Ui.Controls
    4. {
    5. [Serializable]
    6. public class StatusItem
    7. {
    8. public Color ActiveColor { get; set; }
    9. public Color InactiveColor { get; set; }
    10. public bool Active { get; set; }
    11. }
    12. }


    Diese Klasse StatusItem wird nun in einer anderen Klasse verwendet, um eine Property vom Typ List<StatusItem> bereitzustellen:

    C#-Quellcode

    1. using System.Collections.Generic;
    2. using System.Windows.Forms;
    3. using System.ComponentModel;
    4. using System.Drawing;
    5. namespace Control_Sandbox.Ui.Controls
    6. {
    7. public class Status : Control
    8. {
    9. public Status() { items = new List<StatusItem>(); }
    10. private List<StatusItem> items;
    11. [DesignerSerializationVisibility( DesignerSerializationVisibility.Content )]
    12. public List<StatusItem> Items
    13. {
    14. get { return items; }
    15. set
    16. {
    17. items = value;
    18. // some more code here
    19. }
    20. }
    21. protected override void OnPaint(PaintEventArgs e)
    22. {
    23. base.OnPaint( e );
    24. e.Graphics.DrawRectangle( new System.Drawing.Pen( new SolidBrush( Color.Black ) ), 0, 0, Width - 1, Height - 1 );
    25. }
    26. }
    27. }


    Wenn man jetzt im Designer der Eigenschaft Items neue Einträge (Items) hinzufügt und das Projekt anschließend kompiliert, gibt es den als Bild angehangenen Fehler.

    Der Base64-String in der Resx-Datei sieht entschlüsselt so aus:

    Quellcode

    1. FControl Sandbox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nullQSystem.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&Control_Sandbox.Ui.Controls.StatusItem<ActiveColor>k__BackingField<InactiveColor>k__BackingField<Active>k__BackingFieldSystem.Drawing.ColorSystem.Drawing.ColorSystem.Drawing.Colornamevalue
    2. knownColorstate
    3. O

    Also imo nicht ganz Unsinn...

    Mache ich da etwas falsch?
    Bilder
    • Resx Fehler.PNG

      7,73 kB, 1.121×71, 101 mal angesehen
    Dateien

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „TRiViUM“ ()

    @TRiViUM Ich denke, da fehlt irgendwo noch das eine oder das andere Attribut.
    Sieh mal nach (IlSpy), was bei äquivalenten Microsoft-Controls aufgelistet ist.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @ErfinderDesRades
    Meinst du damit nur einen Getter ohne Setter?
    Ich möchte ja nach wie vor die Möglichkeit haben, neue Einträge im Designmodus hinzufügen zu können, was dann nicht mehr möglich wäre, oder?
    Oder welchen Hintergedanken verfolgst du dabei genau?

    @RodFromGermany
    Gute Idee, da hätte ich auch drauf kommen können.
    Jetzt vermute ich auch, dass es an fehlenden Attributen liegt, um genau zu sein vermutlich am Fehlenden Editor-Attribut.
    Da muss ich mich jetzt mal reinfuchsen...

    Ich berichte, wenn ich eine Lösung gefunden habe :saint:
    @ErfinderDesRades
    Hab die Property Items jetzt wie folgt deklariert:

    C#-Quellcode

    1. using System.Collections.Generic;
    2. using System.Windows.Forms;
    3. using System.ComponentModel;
    4. namespace Control_Sandbox.Ui.Controls
    5. {
    6. public class Status : Control
    7. {
    8. public Status() { items = new List<StatusItem>(); }
    9. private List<StatusItem> items;
    10. [DesignerSerializationVisibility( DesignerSerializationVisibility.Content )]
    11. public List<StatusItem> Items { get { return items; } }
    12. }
    13. }


    Du hattest recht, ich kann im Designmode die Property trotz nur dem Getter setzen, aber warum eigentlich?
    Nichts desto trotz kommt immer noch die Meldung mit der ungültigen Resx-Datei.

    Ob meine Vermutung mit dem fehlenden Editor-Attribut richtig war, weiß ich noch nicht.
    Eigentlich ist der Editor, wie er ohne dem Attribut gezeigt wird, ja genau so, wie ich ihn mir vorstelle.

    TRiViUM schrieb:

    Du hattest recht, ich kann im Designmode die Property trotz nur dem Getter setzen, aber warum eigentlich?
    Warum denn nicht?
    Die List ist instanziert, und der Designer kann ihr dann Elemente hinzufügen.
    (das war meine Hoffnung, dass der Designer iwie zu einem Zeitpunkt Elemente hinzuzufügen versucht, wo die List noch nicht instanziert ist - aber war wohl nicht.)
    Es geht übrigens auch so:

    C#-Quellcode

    1. using System.Collections.Generic;
    2. using System.Windows.Forms;
    3. using System.ComponentModel;
    4. namespace Control_Sandbox.Ui.Controls
    5. {
    6. public class Status : Control
    7. {
    8. private readonly List<StatusItem> items = new List<StatusItem>();
    9. [DesignerSerializationVisibility( DesignerSerializationVisibility.Content )]
    10. public List<StatusItem> Items { get { return items; } }
    11. }
    12. }

    TRiViUM schrieb:

    Ich dachte, weil der Setter fehlt.

    Der Setter der Listen-Property wird zum Hinzufügen von Listen-Elementen garnet benötigt.
    Die Liste wird ja nicht gesetzt, sondern die Elemente der Liste.
    Dazu muss man die Liste abrufen (Getter), aber sie neu zu setzen darf keinesfalls geschehen - da wäre ja die vorherige Liste mit all ihren Elementen verloren.
    Deswegen preferiere ich ja auch ein readonly BackingField.

    ErfinderDesRades schrieb:

    Die Liste wird ja nicht gesetzt, sondern die Elemente der Liste.
    Dazu muss man die Liste abrufen (Getter), aber sie neu zu setzen darf keinesfalls geschehen - da wäre ja die vorherige Liste mit all ihren Elementen verloren.
    Jo, jetzt hat's klick gemacht.

    Ich dachte über den Setter bekomme ich mit, wenn Änderungen an der Liste (Element hinzugefügt/gelöscht) vorgenommen werden, dem ist ja nicht so.
    Dazu müsste man sich noch einen Handler drum herum basteln, wie hier beschrieben ist: stackoverflow.com/questions/12…-handle-add-to-list-event

    TRiViUM schrieb:

    Ich dachte über den Setter bekomme ich mit, wenn Änderungen an der Liste (Element hinzugefügt/gelöscht) vorgenommen werden


    Dann würde ich zur ObservableCollection<T>, zu finden im System.Collections.ObjectModel Namespace, greifen. Dort ist diese Funktionalität schon drin....
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

    TRiViUM schrieb:

    Ich dachte über den Setter bekomme ich mit...
    Über den Setter bekommst du garnichts mit, was die Elemente der Liste betrifft.
    Der Setter der Liste setzt die Liste - er setzt nicht: die Elemente.
    Da kannst du sonstwas über Stackoverflow oder mit ObservableCollection versuchen - der Setter setzt die Liste - nicht die Elemente.

    Ist das klar? Der Setter setzt.
    Die Liste.
    Eine Liste ist was anderes als ihre Elemente.
    Der Designer fügt Elemente hinzu.

    Über den Setter könntest du allenfalls mitbekommen, wenn eine andere Liste gesetzt wird - womit dann ja die Elemente der vorherigen Liste weg wären.
    Das aber will niemand - daher: readonly - kein Setter.
    @SpaceyX
    Danke, dass kannte ich noch nicht. Werde ich mir mal genauer anschauen :)

    Dennoch ist ja das eigentliche Problem noch nicht gelöst...
    Muss hier überhaupt explizit ein Editor-Attribut angewendet werden?

    ErfinderDesRades schrieb:

    Ist das klar? Der Setter setzt.Die Liste.
    Jo, wie gesagt, ist angekommen :D
    Ich dachte anfangs, dass wenn die Liste selbst readonly ist, dass man auch nicht ihre Elemente manipulieren kann...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „TRiViUM“ ()

    TRiViUM schrieb:

    Dennoch ist ja das eigentliche Problem noch nicht gelöst
    Der Designer kann keine Controls vertragen mit Properties mit generischem Datentyp.
    Zumindest nachdem ich das geändert hab, funztes bei mir.
    Dateien

    ErfinderDesRades schrieb:

    oh - sorry, geht bei mir doch net.
    Quasi links blinken und dann doch rechts abbiegen :D

    ErfinderDesRades schrieb:

    [...] erforderlich, dass StatusItem in einer anderen Assembly liegt?
    Scheinbar, nur verstehe ich den Grund dafür nicht :huh:

    Gerade gefunden, hier wird vom Prinzip ähnliches Thema durchgeschnuddelt: stackoverflow.com/questions/20…d-not-load-type-error-why
    Komisch, dass das so vom Prinzip nur geht, wenn es aus ner annern Assembly kommt :huh:

    EDIT:
    Ich habe die Lösung gefunden :)
    Die Property nicht vom Typ List<OwnClass> deklarieren, sondern die Property vom Typ ObservableCollection<YourClass> anlegen ^^
    Da kann man dann nämlich auch noch das Event CollectionChanged nutzen...
    Wichtig: Die Property vom Typ ​ObservableCollection mit muss mit dem Attribut ​ [DesignerSerializationVisibility( DesignerSerializationVisibility.Content )] versehen werden, sonst verschwinden nach Kompilieren alle Items aus der Liste im Designer...

    Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von „TRiViUM“ ()