Autor Beitrag
Crideer
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Di 22.10.13 11:41 
Guten Tag,
wie oben beschrieben, ist mein Problem, das Speichern und Laden des Inhaltes einer Listview, finde da leider keine konkrete Lösung.
Zum Programm: Ich habe eine Listview mit 8 Spalten, also 1 Item + 7 Subitems. Er speichert alles korrekt in der txt-Datei nur er lädt immer nur die erste Spalte. Hier mal der Code vom saveButton und openButton:
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:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
        private void saveButton_Click_1(object sender, EventArgs e)
        {
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                FileStream myFileStream = new FileStream(saveFileDialog1.FileName, FileMode.Append, FileAccess.Write);
                StreamWriter myStreamWriter = new StreamWriter(myFileStream);
                myStreamWriter.Flush();

                for (int i = 0; i < listView1.Items.Count; i++)
                {
                    for (int j = 0; j <= 7; j++)
                    {
                        myStreamWriter.Write(listView1.Items[i].SubItems[j].Text + ";");
                    }

                }
                myStreamWriter.Flush();
                myStreamWriter.Close();
            }

        }

        private void openButton_Click_1(object sender, EventArgs e)
        {
            if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                listView1.Items.Clear();
                FileStream myFileStream = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
                StreamReader myStreamReader = new StreamReader(myFileStream);
                myStreamReader.BaseStream.Seek(0, SeekOrigin.Begin);
                string Datei = myStreamReader.ReadLine();
                int nStart = 0;
                while (Datei != null)
                {
                    int nPos1 = Datei.IndexOf(";", nStart); //Sucht die Stelle(Index) bis zur Stelle vor ";". Fängt bei nStart an zu suchen.
                    string str1 = Datei.Substring(nStart, nPos1 - nStart);//Liest einen String Wert aus von der Stelle 0 bis nPos1 -> also bis vor dem Zeichen ";".
                    nStart = nPos1 + 1;                     // Der neue Startpunkt ist hinter ";", da npos1 vor ";" war, also +1.

                    int nPos2 = Datei.IndexOf(";", nStart);
                    string str2 = Datei.Substring(nStart, nPos2 - nStart);
                    nStart = nPos2 + 1;

                    int nPos3 = Datei.IndexOf(";", nStart);
                    string str3 = Datei.Substring(nStart, nPos3 - nStart);
                    nStart = nPos3 + 1;

                    int nPos4 = Datei.IndexOf(";", nStart);
                    string str4 = Datei.Substring(nStart, nPos4 - nStart);
                    nStart = nPos4 + 1;

                    int nPos5 = Datei.IndexOf(";", nStart);
                    string str5 = Datei.Substring(nStart, nPos5 - nStart);
                    nStart = nPos5 + 1;

                    int nPos6 = Datei.IndexOf(";", nStart);
                    string str6 = Datei.Substring(nStart, nPos6 - nStart);
                    nStart = nPos6 + 1;

                    int nPos7 = Datei.IndexOf(";", nStart);
                    string str7 = Datei.Substring(nStart, nPos7 - nStart);
                    nStart = nPos7 + 1;

                    int nPos8 = Datei.IndexOf(";", nStart);
                    string str8 = Datei.Substring(nStart, nPos8 - nStart);
                    nStart = nPos8 + 1;

                    System.Windows.Forms.ListViewItem item = new System.Windows.Forms.ListViewItem(str1);
                    item.SubItems.Add(str2);
                    item.SubItems.Add(str3);
                    item.SubItems.Add(str4);
                    item.SubItems.Add(str5);
                    item.SubItems.Add(str6);
                    item.SubItems.Add(str7);
                    item.SubItems.Add(str8);

                    listView1.Items.AddRange(new System.Windows.Forms.ListViewItem[] { item });

                    Datei = myStreamReader.ReadLine();
                }

                myStreamReader.Close();
            }

        }


Anscheinend führt der die while-Schleife nur einmal durch. Was müsste ich ändern das er es auch solange ausführt bis der Streamreader kein Text mehr erfasst? Oder gibt es gar eine viel leichter Möglichkeit den Inhalt einer LIstview zu speichern und zu laden?Danke im voraus für Antworten :)

Moderiert von user profile iconTh69: C#-Tags gesetzt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4796
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 22.10.13 11:55 
Hallo und :welcome:

bist du denn schon mal mit dem Debugger durch deinen Code gegangen, um zu sehen warum die while-Schleife nur einmal durchlaufen wird?

Üblicherweise programmiert man die Lese-Routine so:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
string line;
while ((line = myStreamReader.ReadLine()) != null)
{
  // ...
}


Und das Extrahieren der einzelnen Spalten geht auch mittels der String.Split-Methode einfacher:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
string[] columns = line.Split(';');

ListViewItem item = new ListViewItem(columns);

listView.Items.Add(item);
Crideer Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Di 22.10.13 12:08 
Danke für die Antwort, und ja ich bin durch den Debugger durchgegangen :)

Sobald ich" Datei = myStreamReader.ReadLine(); " außerhalb der while schleife schreibe, führt er die while schleife auch bis zum ende durch, nur wenn er dann am ende ist führt er es dann noch einmal durch und npos1 ist dann gleich negativ und es erscheint eine Fehlermeldung.

Und danke auch für die anderen Methoden, aber da ich noch ein blutiger Anfänger bin , bin ich nicht wirklich in der Lage meinen Text damit umzuschreiben :o :D
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: Di 22.10.13 12:19 
Zitat:
Sobald ich" Datei = myStreamReader.ReadLine(); " außerhalb der while schleife schreibe,


Ähm dann ist gar kein ReadLine mehr in der Schleife? Dann schaust du bei jedem Schleifendurchlauf immer auf die gleiche Zeile. Das willst du bestimmt nicht.

Zitat:
ende ist führt er es dann noch einmal durch und npos1 ist dann gleich negativ und es erscheint eine Fehlermeldung.


Klingt so als hättest du am Ende der Datei eine leere Zeile. Du solltest in der Schleife auf die Länge der Zeile prüfen um Leerzeilen auszusortieren.
Crideer Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Di 22.10.13 12:32 
@Ralf Jansen:
Beim Speichern wird ja auch alles in eine Zeile geschrieben.
Sollte ich dann beim Speichern dann so ändern, das eine Zeile Listview = eine Zeile txt-Datei entspricht?
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: Di 22.10.13 12:42 
Zeilenweise wäre einfacher. Durch Writeline/Readline hast du dann ja jedes Item durch ein Zeilenumbruch sauber voneinander getrennt.
Du kannst aber auch irgendwas anderes als Trenner nehmen.

Wenn du im Moment alles in eine Zeile schreibst wie hast du denn das letzte Subitem vom 1.Item vom 2.Item getrennt?
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4796
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 22.10.13 12:45 
Hallo Crideer,

genau dies ist mir auch aufgefallen - schön, daß du den Fehler selber gefunden hast.
Und ja, es macht wohl Sinn, daß du dann die Textdatei auch zeilenweise aufbaust (mittels WriteLine).

Trotzdem wundere ich mich, daß du lieber an deinem umfangreicheren Code festhalten willst, anstatt die paar Codezeilen zu übernehmen (es reicht wirklich Copy & Paste: du mußt nur meinen unteren Codeteil in die geschweiften-Klammern der oberen while-Schleife packen - und deine Schleife sowie die 2-3 Zeilen darüber komplett löschen).

Und noch ein Tipp:
statt dem StreamReader könntest du sogar einfach die File.ReadAllLines-Methode benutzen...

Für diesen Beitrag haben gedankt: Crideer
Crideer Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Di 22.10.13 13:11 
Klappt jetzt alles wunderbar :)
Hier nochmal die Codes:
Speichern:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
 private void saveButton_Click_1(object sender, EventArgs e)
        {
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                FileStream myFileStream = new FileStream(saveFileDialog1.FileName, FileMode.Create, FileAccess.Write);
                StreamWriter myStreamWriter = new StreamWriter(myFileStream);
                myStreamWriter.Flush();

                for (int i = 0; i < listView1.Items.Count; i++)
                {
                    for (int j = 0; j <= 7; j++)
                    {
                        myStreamWriter.Write(listView1.Items[i].SubItems[j].Text + ";");
                    }
                    myStreamWriter.WriteLine();
                }
                myStreamWriter.Flush();
                myStreamWriter.Close();
            }

        }


Laden:
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:
 private void openButton_Click_1(object sender, EventArgs e)
        {
            if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                listView1.Items.Clear();
                FileStream myFileStream = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
                StreamReader myStreamReader = new StreamReader(myFileStream);
                myStreamReader.BaseStream.Seek(0, SeekOrigin.Begin);
                string line;
                while ((line = myStreamReader.ReadLine()) != null)
                {
                    string[] columns = line.Split(';');

                   System.Windows.Forms.ListViewItem item = new System.Windows.Forms.ListViewItem(columns);

                    listView1.Items.Add(item);
 
                }
                myStreamReader.Close();
   
            }

        }


Und wie setze ich die File.ReadAllLines-Methode ein statt den StreamReader? :)
[Edit]: In den Programm habe ich noch zusätzlich 4 Labels die dann auch gespeichert werden müssten in der selben Datei und auch ausgelesen werden müssten. Mein Problem ist wie ich das mache, das das Programm das nicht dann in die Listview reinschreibt anstatt in die Labels?:o