Entwickler-Ecke

Basistechnologien - Einen Denkfehler bei Dictionary


Delete - So 06.03.16 00:02
Titel: Einen Denkfehler bei Dictionary
Hallo. Ich bin neu in diesem Forum und habe eine Frage :-)

Ich habe ein Dictionary<RichTextBox, string>();
Wenn ich in meiner Anwendung neue Dateien hinzufüge, klappt alles super. Auch beim öffnen haut alles hin. Wenn ich das Projekt jedoch spichern möchte, dass wird nur der voherige Text jeder RichTextBox gespeichert. Ich weiß auch warum: beim Öffnen wird das Dictionary gefüllt und behält somit die alten Daten auch beim Speichern. Aber wie bekomme ich den neuen Text in das Dictionary?

Hier der Speicheralgorithmus:

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:
try
            {
                if ((HauptPfad != "") && (this.tabControl1.TabPages.Count > 0))
                {
                    this._dictionary.Clear();
                    foreach (var v in this._dictionary)
                    {
                        using (StreamWriter writer = new StreamWriter(v.Value.ToString()))
                        {
                            foreach (var line in v.Key.Lines)
                            {
                                writer.WriteLine(line.ToString());
                            }
                            writer.Close();
                        }
                    }
                }
                else
                {
                    MessageBox.Show("Sie können die Dateien nicht speichern, da Sie erst ein neues Projekt anlegen müssen oder Sie müssen ein Projekt öffnen.""Leerer Pfad", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }


Die RichTextBoxen lieger auf einer TabPage in einer TabControl. Für jede Antwort bin ich dankbar :)


Christian S. - So 06.03.16 01:06

Hallo und :welcome:!

Aus Deiner Beschreibung werde ich irgendwie nicht so wirklich schlau. Versuche mal, Dich in die Sichtweise einer Person zu versetzen, die Dein Programm gar nicht kennt und lies Deinen Beitrag mal mit deren Augen :-)

Was mir aber aufgefallen ist:

C#-Quelltext
1:
2:
3:
                    this._dictionary.Clear();
                    foreach (var v in this._dictionary)
                    {

Du leerst in der ersten Zeile das Dictionary, dessen Einträge Du dann durchlaufen willst. Da ist was krumm. ;-)

Viele Grüße
Christian


Delete - So 06.03.16 12:32

Vielen Dank für die schnelle Antwort :)

Also beim Öffnen wird das Dictionary mit der RichTextBox und einem Pfad gefüllt. Angenommen der text der RTB ist nun Hallo. Dann bleibt dieser Text ja in der gesamten Programmlaufzeit Hallo. Auch wenn ich noch Welt! hinzufügen. Und Dictionary.Clear(); sollte dort eigentlich nicht rein :oops:

Öffnen Code:

C#-Quelltext
1:
2:
3:
4:
5:
NeuesProjekt n = new NeuesProjekt();
            n._html += new NeuesProjekt.HTML(HyperTextMarkupLanguage);
            n._css += new NeuesProjekt.CSS(CSS);
            n._javascript += new NeuesProjekt.JavaScript(JavaScript);
            n.Show();



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
HauptPfad = Pfad;

            TabPage t = new TabPage("Index.html");
            t.BackColor = _einstellungen.BackGroundColor;

            RichTextBox r = new RichTextBox();
            r.AcceptsTab = true;
            r.Text = Text;
            r.Font = _einstellungen.Font;
            r.ForeColor = _einstellungen.ForeColor;
            r.BackColor = _einstellungen.BackGroundColor;
            r.Dock = DockStyle.Fill;

            t.Controls.Add(r);
            this.tabControl1.TabPages.Add(t);
            _dictionary.Add(r, Path.Combine(Pfad, "Index.html"));


Speichern:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
if ((HauptPfad != "") && (this.tabControl1.TabPages.Count > 0))
                {
                    foreach (var v in this._dictionary)
                    {
                        using (StreamWriter writer = new StreamWriter(v.Value.ToString()))
                        {
                            foreach (var line in v.Key.Lines)
                            {
                                writer.WriteLine(line.ToString());
                            }
                            writer.Close();
                        }
                    }
                }


Ralf Jansen - So 06.03.16 14:20

Zitat:
Angenommen der text der RTB ist nun Hallo. Dann bleibt dieser Text ja in der gesamten Programmlaufzeit Hallo.


Nein wenn du in der UI den Text in der RichTextBox änderst sollte der sich zur Laufzeit auch in den Properties der RichTextBox wiederfinden. Egal ob du auf die Rtf, Text oder Lines Property zugreift. Auch wenn du über ein Dictionary auf die RichTextBox zugreifst sollte es so sein. Wenn sich der Text in der RichTextBox die du im Dictionary findest nicht mit ändert würde ich mich fragen ob das noch die RichTextBox ist die angezeigt wird oder eine andere.

Wofür ist die If Abfrage bevor du über das Dictionary iterierst zum speichern? Weder Hauptpfad noch das TabControl und dessen TabPages benutzt du innerhalb des Code Blocks.
Da ToString() in v.Value.ToString() sowie line.ToString() ist überflüssig. Sowohl v.Value als auch line sind bereits strings.


C# - So 06.03.16 14:23

Also aus dem bisherigen Code sehe ich keinen Grund, warum dein Problem auftritt. Ersetzt du irgendwo im Code vielleicht die RichTextBox in deinem TabControl? Du könntest auch mal deinen Code zum Testen etwas abändern und das Dictionary mal ignorieren.

Schreibe den Dateipfad beim Öffnen in die Tag-Eigenschaft der zugehörigen RichTextBox. Beim Speichern filterst du dann deine RichTextBoxen direkt aus der TabPage-Eigenschaft.

Öffnen:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
HauptPfad = Pfad;

            TabPage t = new TabPage("Index.html");
            t.BackColor = _einstellungen.BackGroundColor;

            RichTextBox r = new RichTextBox();
            r.AcceptsTab = true;
            r.Text = Text;
            r.Font = _einstellungen.Font;
            r.ForeColor = _einstellungen.ForeColor;
            r.BackColor = _einstellungen.BackGroundColor;
            r.Dock = DockStyle.Fill;
            r.Tag = Path.Combine(Pfad, "Index.html");

            t.Controls.Add(r);
            this.tabControl1.TabPages.Add(t);


Speichern:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
if ((HauptPfad != "") && (this.tabControl1.TabPages.Count > 0))
                {
                    foreach (var rtb in tabControl1.TabPages.Cast<TabPage>().SelectMany(tabPage => tabPage.Controls.OfType<RichTextBox>()))
                    {
                        using (StreamWriter writer = new StreamWriter((string) rtb.Tag))
                        {
                            foreach (var line in rtb.Lines)
                            {
                                writer.WriteLine(line);
                            }
                            writer.Close();
                        }
                    }
                }


Im foreach-Header werden alle RichTextBoxen aus dem TabControl extrahiert. Die Variable rtb ist eine RichTextBox.