Listen von Klassen in Komponenten speichern

xbu58

Mitglied
Hallo

Wie einige sicher gelesen haben, hatte ich das Problem, dass eine Liste von Klassen innerhalb einer Komponente nicht in die Form1.Designer.cs sondern in die Form1.resx gespeichert wurde und das dummerweise auch noch Binär (siehe http://www.tutorials.de/forum/c-c/291626-list-t-speichern.html#post1505006. Das Grundlegende Konstrukt, welches ich dafür verwendet hatte war:
C#:
  public class Dialogs : System.ComponentModel.Component
  {
     ....
    internal List<DialogDataClass> dialogData = new List<DialogDataClass>();
    ....
An und für sich funktioniert das erfassen von Listen im VS so problemlos, aber eben gespeichert wird Binär. Das ist in Fällen, bei denen auf die Daten von einem anderen Programm zugegriffen werden soll, was bei einer Sprach-Übersetzung durch Dritte der Fall ist, schlicht nicht brauchbar ist. Also habe ich nach einer Lösung gesucht, welche hier Abhilfe schafft. Die Lösung ist relativ einfach (nur kommt man nicht so einfach drauf.... :rolleyes: ) und zwar, indem man mit einer Collection-Klasse arbeitet. Diese zeige ich nun in folgenden Konstrukt auf.
Hauptklasse:
C#:
  public class Dialogs : System.ComponentModel.Component
  {
     ....
    internal DialogItemCollection dialogData = new DialogItemCollection();    

    ....

    [Category("Data")]
    [Description("Liste der gespeichert Dialogs")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    [Editor(typeof(System.ComponentModel.Design.CollectionEditor), typeof(System.Drawing.Design.UITypeEditor))]
    public DialogItemCollection DialogData
    {
      get { return dialogData; }
      set { dialogData = value; }
    }
  }
Die folgende Collection-Definition ist natürlich nicht vollständig, zeigt aber das Konzept. Es müssen mindestens die Methoden AddRange, Add, Insert, CopyTo, IndexOf, Remove und Contains implementiert sein.
Collection-Klasse:
C#:
  public delegate void CollectionUpdatedHandler(object sender, EventArgs e);

  public class DialogItemCollection : CollectionBase, IList
  {
    public event CollectionUpdatedHandler CollectionUpdated;

    public MsgBoxItem this[int index]
    {
      get { return (MsgBoxItem)List[index]; }
    }

    public void AddRange(MsgBoxItem[] items)
    {
      foreach (MsgBoxItem xItem in items)
        this.List.Add(xItem);
      OnCollectionUpdated();
    }
....
    public bool Contains(MsgBoxItem value)
    {
      return this.List.Contains(value);
    }

    protected virtual void OnCollectionUpdated()
    {
      if (CollectionUpdated != null)
        CollectionUpdated(this, new EventArgs()); 
    }
  }
Bei der Dialog-Klasse ändert sich nichts, bis darauf, dass sie NICHT als [Serializable] definiert werden darf.
Daten-Klasse:
C#:
  public class DialogDataClass
  {
    private static int count = 0; // ist nicht unbedingt nötig
    private string name = "";
    private string title = "";
    private string text = "";

    // ist nicht unbedingt nötig
    public DialogDataClass()
    {
      count++;
      name = string.Format("Dialog_{0}", count.ToString().PadLeft(3, '0'));
    }

    // ist nicht unbedingt nötig
    [Browsable(false)]
    private int Count
    {
      get { return count; }
    }

    ....
    
    [Category("Design")]
    [Description("Name der Dialog-Box")]
    [DisplayName("(Name)")]
    public string Name
    {
      get { return name; }
      set { name = value; }
    }
    
    [Category("Data")]
    [Description("Titel der Dialog-Box")]
    public string Title
    {
      get { return title; }
      set { title = value; }
    }

    [Category("Data")]
    [Description("Text der Dialog-Box")] 
    public string Text
    {
      get { return text; }
      set { text = value; }
    }
     ....
  }

Ich hoffe, dass dieses Beispiel euch hilft, ähnliche Probleme zu lösen, ohne dass ihr euch durch eine nicht gerade erhellende Help lesen müsst, wie ich das machen musste.

Gruss
Xaver
 
Zuletzt bearbeitet von einem Moderator:
Zurück