Autor Beitrag
mandawar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 25

Win XP, Suse 9.0
3.0
BeitragVerfasst: Do 09.04.09 11:59 
Hi

ich baue mir in meinem Programm einen TreeView auf der einer Ordnerstruktur auf dem Desktop ähnelt. Allerdings sind die Nodes darin keine normalen TreeNodes, sondern haben jedes noch 5 extra Attribute.
Nun möchte ich den TreeView in einer XML abbilden, damit dieser wieder geladen werden kann und alle Nodes wieder ihre Eigenschaften und Attribute erhalten.
Das ganze muss dann eben auch wieder lesbar sein. Ich habe nun noch ein Problem mit der Umsetzung der XML Struktur und mit der Programmtechnischen Umsetzung - vor allem was das hinzufügen von Childs betrifft.
Ich weis nicht nach was ich die Nodes strukturieren soll? Nach Index im TreeView geht glaube nicht, da die ChildNodes dabei nicht erfasst werden. Also würde ich den Namen wählen..

Wie könnte ich dann die XML aufbauen?
Jeder Node hat evtl. Unternodes und 6 Properties...

Liebe Grüße und schönes Osterfest

Basti
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Do 09.04.09 14:16 
Eigene TreeNodes sind ein schlechter Ansatz, da View und Model vermischt werden. Das bekommst du jetzt zu spüren ;) .
Beschreibe das Model mit einer gewöhnlichen, GUI-unabhängigen Baumstruktur (POCOs), also etwa:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
class MyDirectory
{
  public string Name { get; set; }
  public IList<MyDirectory> SubDirectories { get; set; }
}

Dieses Model kannst du jetzt über eine rekursive Funktion (wir sind ja leider nicht bei WPF ;) ) und TreeNode.Tag auf die TreeView abbilden.
Und was bringt das nun? Erstens Übersichtlichkeit, Seperation of Concerns usw., zweitens kann jetzt der XmlSerializer das Speichern und Laden ohne eine weitere Zeile Code übernehmen.

_________________
>λ=
mandawar Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 25

Win XP, Suse 9.0
3.0
BeitragVerfasst: Di 21.04.09 11:17 
Hi
ich habe versucht mein Programm auf dieses Model umzubauen - klappt auch soweit :)
Meine Klasse (kleiner Schreibfehler in der Liste ;) ):
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
    public class MyDirectory
    {
        public string Dateiname;
        public string Typ;
        public string Status;
        public string Bearbeiter;
        public bool Finished;
        public string letzteAenderung;
        public IList<MyDirectory> SubDiretories;
    }


rekursive Funktion:
ausblenden volle Höhe 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:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
        private void OrdnerAbbilden(string Ordner, MyDirectory ParentDirectory)
        {
            string[] strOrdnerInhalt = Directory.GetFileSystemEntries(Ordner);
            foreach (string s in strOrdnerInhalt)
            {
                if (!s.Contains("tools"))
                {
                    if ((File.GetAttributes(s) & FileAttributes.Directory) == FileAttributes.Directory)
                    {
                        MyDirectory ChildDirectory = new MyDirectory();
                        ChildDirectory.Dateiname = s;
                        ChildDirectory.Typ = "Ordner";
                        ChildDirectory.Status = "";
                        ChildDirectory.Bearbeiter = "";
                        ChildDirectory.letzteAenderung = DateTime.UtcNow.ToString();
                        OrdnerAbbilden(s, ChildDirectory);
                        ParentDirectory.SubDiretories.Add(ChildDirectory);
                    }
                    else
                    {
                        MyDirectory ChildDirectory = new MyDirectory();
                        ChildDirectory.Dateiname = s;
                        switch (Path.GetExtension(s))
                        {
                            case ".p"
                                ChildDirectory.Typ = "Procedure";
                                break;
                            case ".w":
                                ChildDirectory.Typ = "Window";
                                break;
                            case ".bmp":
                                ChildDirectory.Typ = "Bitmap";
                                break;
                            case ".jpg":
                                ChildDirectory.Typ = "Jpeg-Bild";
                                break;
                            case ".i":
                                ChildDirectory.Typ = "Include";
                                break;
                            default:
                                ChildDirectory.Typ = "Datei";
                                break;
                        }
                        ChildDirectory.Status = "";
                        ChildDirectory.Bearbeiter = "";
                        ChildDirectory.letzteAenderung = DateTime.UtcNow.ToString();
                        ParentDirectory.SubDiretories.Add(ChildDirectory);
                    }
                }
            }
        }


Aufruf:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
            MyDirectory RootDirectory = new MyDirectory();
            RootDirectory.Typ = "Ordner";
            RootDirectory.Dateiname = @"\\bla\blablub\y41d";
            RootDirectory.letzteAenderung = DateTime.UtcNow.ToString();
            RootDirectory.Bearbeiter = "";
            RootDirectory.Status = "";
            OrdnerAbbilden(@"\\bla\blablub\y41d", RootDirectory);


Problem:
Wenn in der rekursiven Funktion das erste mal ein ChildDirectory in die IList<MyDirectory> eingetragen werden soll sagt mir der Debugger NullRefException. Speziell betrifft das die Zeile ParentDirectory.SubDiretories.Add(ChildDirectory); nach der Switch-Anweisung. Datei haben aber sowohl ParentDirectory, als auch ChildDirectory Werte.
Nun wäre meine Vermutung, dass die IList<MyDirectory> entweder nicht korrekt instanziiert wurde, oder dass die Liste eine spezielle Art von Parametern erwartet - allerdings weis ich nicht genau welche ^^
Andere Vermutung wäre die Instanziierung der Objekte aus der MyDirectory-Klasse - baut der Compiler das Objekt korrekt auf mittels des Aufrufs "MyDirectory RootDirectory = new MyDirectory();", obwohl ich nicht explizit einen Konstruktor in der Klasse erzeugt habe?

Weis jemand von euch woran das liegen kann?

Liebe Grüße
Basti
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Di 21.04.09 11:23 
Hallo,

das Problem liegt darain, dass du die IListe<MyDirectory> SubDirectories zwar so deklarierst, aber nicht initialisierst. Der wert von SubDirectories ist deshalb null und du erhälst beim Zugriff ein NullRefException.

Initialisier das Objekt deshal mit:
public IList<MyDirectory> SubDiretories = new IList<MyDirectory>();

Gruß Daniel
mandawar Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 25

Win XP, Suse 9.0
3.0
BeitragVerfasst: Di 21.04.09 11:33 
Hi,
ich habe deinen Tip jetzt in der Klassendeklaration umgesetzt, bekomme allerdings: "Es konnte keine Instanz der abstrakten Klasse oder Schnittstelle "System.Collections.Generic.IList<Umstellungsverwaltung_XML.MyDirectory>" erstellt werden."
:(
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Di 21.04.09 11:39 
Ah sorry,
du musst einen konkrete Klasse nehmen, die das IList-Interface implementiert.
Zum Beispiel: Vector oder List.
mandawar Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 25

Win XP, Suse 9.0
3.0
BeitragVerfasst: Di 21.04.09 11:51 
Ah danke, jetzt funktioniert es :)
Werd mir gleich mal durchlesen was abstrakte und konkrete Klassen sind