Text wird nicht in Textdatei geschrieben

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Text wird nicht in Textdatei geschrieben

    Hallo, ich mach es einfach mal kurz und Knapp: Ich teste ein wenig herum, und wollte ein Speichersystem erstellen. Ich habe ein TextBox, dessen Text in einer .txt gespeichert werden soll. Wenn ich auf den Speichern Knopf drücke, wird der Ordner erstellt, die Textdatei mit dem jeweiligen Namen (Den man sich aussuchen kann) erstellt und alle Dateinamen die in dem Ordner sind werden in einer Listbox aufgelistet. Dies Funktioniert wunderbar, jedoch habe ich ein Problem: Den Text den ich in die TextBox schreibe wird nicht gespeichert. Die .txt wird erstellt, jedoch ohne Text. ich bekommen auch keine Fehlermeldung.

    Hier mein Code:

    Dies passiert wenn sich das Programm öffnet:
    Spoiler anzeigen

    Visual Basic-Quellcode

    1. Public Class Hauptfenster
    2. ' Variablen
    3. Public Pfad As String = "C:\TestTest1\"
    4. Public Datei As String
    5. Public Leer As String = ""
    6. Public Script As String
    7. Public auflistung
    8. Public Script_Text_V As String
    9.  
    10.  
    11. ' Speichersystem
    12. Private Sub SpeichernToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SpeichernToolStripMenuItem.Click
    13. Speichern_Name.Show()
    14. End Sub
    15.  
    16.  
    17. Public Sub Hauptfenster_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    18. Dim Script_Text_V As String = Script_Text.Text
    19. Dim dir As New System.IO.DirectoryInfo(Me.Pfad)
    20. Me.Script_Auflister.Items.Clear()
    21. For Each file As System.IO.FileInfo In dir.GetFiles
    22. Me.Script_Auflister.Items.Add(file.Name)
    23. Next
    24. End Sub
    25.  
    26.  
    27.  
    28.  
    29. End Class


    Wenn ich auf Speichern drücke geschieht dies:
    Spoiler anzeigen

    Visual Basic-Quellcode

    1. Public Class Speichern_Name
    2. 'Speichersystem
    3. Private Sub Speichern_Knopf_Click(sender As Object, e As EventArgs) Handles Speichern_Knopf.Click
    4.  
    5. ' Checkt ob ein Name zugewiesen wird oder nicht
    6. If Name_Script.Text = Hauptfenster.Leer Then
    7. MsgBox("Bitte geben Sie einen Namen an!")
    8. Else
    9. ' Name wurde zugewiesen
    10. Hauptfenster.Script = Hauptfenster.Script_Text_V
    11. Hauptfenster.Datei = "C:\TestTest1\" + Name_Script.Text + ".txt"
    12. ' Test ob Pfad Existiert
    13. If (System.IO.Directory.Exists(Hauptfenster.Pfad)) Then
    14. OrdnerErstellt:
    15. 'Pfad Existiert
    16. If (System.IO.File.Exists(Hauptfenster.Datei)) Then
    17. 'Datei Existiert
    18. Speichern_Name_Vorhanden.Show()
    19. Else
    20. 'Datei Existiert nicht
    21. System.IO.File.WriteAllText(Hauptfenster.Datei, Hauptfenster.Script_Text_V)
    22. Dim dir As New System.IO.DirectoryInfo(Hauptfenster.Pfad)
    23. Hauptfenster.Script_Auflister.Items.Clear()
    24. For Each file As System.IO.FileInfo In dir.GetFiles
    25. Hauptfenster.Script_Auflister.Items.Add(file.Name)
    26. Next
    27. End If
    28. Else
    29. 'Pfad existiert nicht
    30. IO.Directory.CreateDirectory(Hauptfenster.Pfad)
    31. GoTo OrdnerErstellt
    32. End If
    33. End If
    34. Close()
    35. End Sub

    Wie ihr seht, wird ein Fenster geöffnet wenn der Dateiname bereits vorhanden ist
    Wenn ich bei diesem auf "Ja" drücke, soll die Datei überschrieben werden, dabei passiert einfach das gleiche wie bei dem Reiter: 'Datei Existiert nicht

    Ich hoffe ich habe euch nun nicht mit Infos überhäuft und das ihr mir helfen könnt :)

    Daenni schrieb:

    VB.NET-Quellcode

    1. GoTo OrdnerErstellt
    Stell das Programm so um, dass Du ohne GoTo auskommst. Hatten wir bereits.
    Und:
    Warum hast Du VB6 angeklickt? Ändere das bitte.

    Daenni schrieb:

    VB.NET-Quellcode

    1. Speichern_Name.Show()
    Gugst Du hier.
    Wenn Du das verstanden und umgesetzt hast, ist Dein Problem gelöst. :thumbsup:


    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!
    Ich hab nun mehrfach Probiert es zu verstehen und umzusetzen.. leider ist die Seite für mich nur verwirrend. Ich verstehe das es wohl daran liegt wie ich die Form aufrufe, jedoch kapier ich ehrlich gesagt kein Wort von dem Post. Mir ist beim durchlesen auch nicht klar welcher Teil des Postes mir bei meinem Problem helfen könnte. Würde es gerne selber herausfinden und es verstehen, das ist ja klar, aber mit dem Post komm ich nicht klar.. die menge erschlägt mich einfach.. wenn du mir eventuell die Stelle im Post sagen könntest bei der ich meine Lösung bzw. den Lösungsansatz finde wäre es sehr nett von dir :)
    Trotzdem danke für die Hilfe, leider bin ich zu doof sie zu kapieren ;)
    Du arbeitest wohl zu allererst nicht mit:

    VB.NET-Quellcode

    1. Option Strict On
    in Deinen Einstellungen!

    Ansonsten würde z.B. sofort folgender Unsinn angemeckert werden:

    VB.NET-Quellcode

    1. Public auflistung
    Was soll das sein???

    Du definierst einmal als Public:

    VB.NET-Quellcode

    1. Public Script_Text_V As String

    dann in der Load-Routine abermals:

    VB.NET-Quellcode

    1. Dim Script_Text_V As String = Script_Text.Text

    Wenn dann definiere gleich nur einmalig:

    VB.NET-Quellcode

    1. Public Script_Text_V As String = Script_Text.Text

    Evtl. könnte dann Dein Programm funktionieren - aber ich steige wirklich nicht durch all Deine Bezeichnungen durch!

    Daenni schrieb:

    Lösungsansatz
    Du musst in Instanzen denken, objektorientiert.
    Wenn Du von der Hauptklasse in eine Unterklasse (kann auch ne Form sein) was reinreichen willst, machst Du in der Unterklasse eine Property, die Du von außen lesen und schreiben kannst.
    Wenn die Unterklasse der Hauptklasse was mitzuteilen hat, gib der Unterklasse ein Event, das die Hauptklasse abonieren muss.
    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!
    @Daenni

    Habe für Dich eine kleine Anwendung, die verdeutlichen soll, was @RodFromGermany meint.

    Diese Anwendung soll folgende einfache Formel berechen: a2 = b
    Eingabe von "a" auf Form1 und allein zu Übungszwecken Ausgabe von "b" auf Form2

    Hier der Code für Form1:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On ' Nur für alle - die es immer noch nicht standardmäßig in den Einstellungen haben.
    2. ' Zu berechnen sei: a hoch 2 gleich b
    3. ' Eingabe von "a" auf Form1 und allein zu Übungszwecken Ausgabe von "b" auf Form2
    4. ' Der Button und das NumericUpDown werden hier in der Subroutine New angelegt - erfolgt normalerweise mit Hilfe des Designers!
    5. Public Class Form1
    6. Friend WithEvents bt1 As Button
    7. Friend WithEvents a As NumericUpDown
    8. Public Sub New()
    9. ' Dieser Aufruf ist für den Designer erforderlich.
    10. InitializeComponent()
    11. ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
    12. Me.a = New NumericUpDown()
    13. Me.a.Location = New System.Drawing.Point(49, 139)
    14. Me.a.Maximum = CType(Math.Sqrt(Decimal.MaxValue), Decimal) - 1
    15. Me.a.Name = "a"
    16. Me.a.Size = New System.Drawing.Size(120, 20)
    17. Me.Controls.Add(a)
    18. Me.bt1 = New Button
    19. Me.bt1.Location = New System.Drawing.Point(49, 196)
    20. Me.bt1.Name = "bt1"
    21. Me.bt1.Size = New System.Drawing.Size(150, 23)
    22. Me.bt1.Text = "Berechne: a hoch 2"
    23. Me.Controls.Add(bt1)
    24. End Sub
    25. Private Sub bt1_Click(sender As System.Object, e As System.EventArgs) Handles bt1.Click
    26. Using frm2 As New Form2
    27. frm2.Quadrat(a.Value)
    28. frm2.ShowDialog()
    29. End Using
    30. End Sub
    31. End Class


    Und hier der Code für Form2:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form2
    2. ' Zu berechnen sei: a hoch 2 gleich b
    3. ' Eingabe von "a" auf Form1 und allein zu Übungszwecken Ausgabe von "b" auf Form2
    4. ' Das NumericUpDown wird hier in der Subroutine New angelegt - erfolgt normalerweise mit Hilfe des Designers!
    5. Friend WithEvents b As NumericUpDown
    6. Public Sub New()
    7. ' Dieser Aufruf ist für den Designer erforderlich.
    8. InitializeComponent()
    9. ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
    10. Me.b = New NumericUpDown()
    11. Me.b.Location = New System.Drawing.Point(49, 139)
    12. Me.b.Maximum = Decimal.MaxValue
    13. Me.b.Name = "b"
    14. Me.b.Size = New System.Drawing.Size(120, 20)
    15. Me.Controls.Add(b)
    16. End Sub
    17. Public Sub Quadrat(a As Decimal)
    18. b.Value = a * a
    19. End Sub
    20. End Class




    Frage an @RodFromGermany oder an alle die mit OOP gut bewandert sind:

    Was ist zu programmieren, wenn da 20 Variablen oder mehr von Form1 in Form2 benötigt werden?

    Klar, die könnten alle als Argumente übergeben werden, aber dies wäre ein ellenlanger Aufruf.

    Und natürlich könnten alle diese Variablen erst in eine Klasse gesteckt werden und dann wird die Instanz der Klasse als Argument übergeben.

    Persönlich neige ich ehrlicherweise dann eben in solchen extremen Fällen manchmal aus Bequemlichkeit immer noch zu so etwas wie "Form1.a.Value" in Form2.

    Kommentar zu Post 7 von @ErfinderDesRades: Hmm - ich bin doch (beim Programmieren) super-faul - und nicht unbedingt super-sauber. :huh: :( ;)

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

    Thias schrieb:

    Was ist zu programmieren, wenn da 20 Variablen oder mehr von Form1 in Form2 benötigt werden?
    Ja, da muss man - will man super-sauber bleiben - tatsächlcih ein Daten-Objekt haben mit 20 Properties.
    Ansonsten kann das MainForm ja auch ins Sub-Form reingrabschen, und die 20 Controls auslesen.
    Also das Event muss nicht unbedingt 20 Properties haben.

    Oft (oder meist) kann man allerdings auch Databinding für sich arbeiten lassen, dann codet der Designer den BoilerPlate-Code.

    Thias schrieb:

    20 Variablen
    würde ich in eine separate Datenklasse packen und die als Instanz handeln.
    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 schrieb:

    Ansonsten kann das MainForm ja auch ins Sub-Form reingrabschen, und die 20 Controls auslesen.

    Da kommt bei mir dann doch noch eine Frage hoch.

    Warum ist es OK, dass die MainForm in die Sub-Form "reingrabschen" darf, aber nicht die Sub-Form in die MainForm. Wer hat dieses Gesetz warum aufgestellt?

    Thias schrieb:

    "reingrabschen"
    Da gilt die Ordnung Hauptklasse und Unterklasse.
    Die Instanz der Unterklasse liegt in der Hauptklasse, da ist der Zugriff eben ganz easy.
    Die Unterklasse ist gekapselt, die soll nix von der "Außenwelt" wissen müssen, also kein "grapschen", sondern Events: "Herr Lehrer, ich weiß was".
    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!
    So nachdem ich Events durch @RodFromGermany Erklärung: "Events: Herr Lehrer, ich weiß was" nun noch besser verstanden habe, habe ich die simple Anwendung, welche a2 = b berechnet, noch durch Events erweitert.

    Form1:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On ' Nur für alle - die es immer noch nicht standardmäßig in den Einstellungen haben.
    2. ' Zu berechnen sei: a hoch 2 gleich b
    3. ' Eingabe von "a" auf Form1 und allein zu Übungszwecken Ausgabe von "b" auf Form2
    4. ' Der Button und das NumericUpDown werden hier in der Subroutine New angelegt - erfolgt normalerweise mit Hilfe des Designers!
    5. Public Class Form1
    6. Friend WithEvents bt1 As Button
    7. Friend WithEvents a As NumericUpDown
    8. Private WithEvents frm2 As Form2
    9. Public Sub New()
    10. ' Dieser Aufruf ist für den Designer erforderlich.
    11. InitializeComponent()
    12. ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
    13. Me.a = New NumericUpDown()
    14. Me.a.DecimalPlaces = 2
    15. Me.a.Location = New System.Drawing.Point(49, 139)
    16. Me.a.Maximum = CType(Math.Sqrt(Decimal.MaxValue), Decimal) - 1
    17. Me.a.Name = "a"
    18. Me.a.Size = New System.Drawing.Size(120, 20)
    19. Me.Controls.Add(a)
    20. Me.bt1 = New Button
    21. Me.bt1.Location = New System.Drawing.Point(49, 196)
    22. Me.bt1.Name = "bt1"
    23. Me.bt1.Size = New System.Drawing.Size(150, 23)
    24. Me.bt1.Text = "Zuerst Form2 anzeigen" ' dort mittels Button Event wirklich berechnen: a hoch 2 = b
    25. Me.Controls.Add(bt1)
    26. End Sub
    27. Private Sub bt1_Click(sender As System.Object, e As System.EventArgs) Handles bt1.Click
    28. If frm2 Is Nothing OrElse frm2.IsDisposed Then frm2 = New Form2
    29. If Not frm2.Created Then
    30. frm2.Show(Me)
    31. Else
    32. frm2.Visible = True
    33. frm2.Focus()
    34. End If
    35. End Sub
    36. Private Sub Form2_Click(sender As System.Object, e As System.EventArgs) Handles frm2.MyEvent
    37. ' MessageBox.Show("Event empfangen")
    38. frm2.Quadrat(a.Value)
    39. End Sub
    40. End Class

    Form2:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form2
    2. ' Zu berechnen sei: a hoch 2 gleich b
    3. ' Eingabe von "a" auf Form1 und allein zu Übungszwecken Ausgabe von "b" auf Form2
    4. ' Der Button und das NumericUpDown werden hier in der Subroutine New angelegt - erfolgt normalerweise mit Hilfe des Designers!
    5. Friend WithEvents b As NumericUpDown
    6. Friend WithEvents bt1 As Button
    7. Public Event MyEvent(sender As System.Object, e As System.EventArgs)
    8. Public Sub New()
    9. ' Dieser Aufruf ist für den Designer erforderlich.
    10. InitializeComponent()
    11. ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
    12. Me.b = New NumericUpDown()
    13. Me.b.DecimalPlaces = 4
    14. Me.b.ReadOnly = True
    15. Me.b.Location = New System.Drawing.Point(49, 139)
    16. Me.b.Maximum = Decimal.MaxValue
    17. Me.b.Name = "b"
    18. Me.b.Size = New System.Drawing.Size(120, 20)
    19. Me.Controls.Add(b)
    20. Me.bt1 = New Button
    21. Me.bt1.Location = New System.Drawing.Point(49, 196)
    22. Me.bt1.Name = "bt1"
    23. Me.bt1.Size = New System.Drawing.Size(200, 23)
    24. Me.bt1.Text = "Nun durch Event auslösen berechnen"
    25. Me.Controls.Add(bt1)
    26. End Sub
    27. Public Sub Quadrat(a As Decimal)
    28. b.Value = a * a
    29. End Sub
    30. Private Sub bt1_Click(sender As System.Object, e As System.EventArgs) Handles bt1.Click
    31. RaiseEvent MyEvent(Me, EventArgs.Empty)
    32. End Sub
    33. End Class


    Natürlich lässt sich dies ohne Events schneller und einfacher berechnen (s.o.) - aber es geht ja darum die Funktion von Events zu demonstrieren - insbesondere für @Daenni.

    Edit @Daenni: Falls Du damit immer noch nicht klar kommst, dann poste bitte mal evtl. Deine Form1.Desigenr.vb und Form2.Designer.vb oder halt das ganze Projekt gezippt - denn Deinen Form-Aufbau ansonsten nachzuvollziehen ist so gut wie unmöglich!

    Dieser Beitrag wurde bereits 10 mal editiert, zuletzt von „Thias“ ()

    Thias schrieb:

    Warum ist es OK, dass die MainForm in die Sub-Form "reingrabschen" darf, aber nicht die Sub-Form in die MainForm. Wer hat dieses Gesetz warum aufgestellt?

    Ein Programm ist eine Baumstruktur von Objekten.
    Also ein Objekt, das beinhaltet einige Objekte, davon einige beinhalten viele Objekte, davon viele ganz viele, davon...

    Jedes Objekt ist programmiert.

    Wenn also ein Datentyp einen anderen Datentyp beinhaltet, dann isser abhängig von dem.
    Also das Prog kompiliert nur, wenn im Code vom Owner der Datentyp des SubObjekts bekannt ist.
    Das Subobjekt ist aber unabhängig, und dadurch ist es besser wiederverwendbar.

    Also ein Form mit einem ChangeFont-Button.
    Das Form kennt den Button, der Button kennt das Form aber nicht.
    So kann das Form den Button-Click empfangen, und seinen Font changen.
    Würde der Button selbst ins Form grabschen, und da den Font changen, dann könnte man die Button-Klasse nur noch für dieses eine Form verwenden.
    Was natürlich Crap wäre, zuende gedacht müsste man ja millionen verschiedene Button-Klassen Coden, und jede bewirkt was anderes in anderen Forms, wies grad erforderlich.

    hmm - ich glaub besser erklärt habichs hier: home.arcor.de/eckardahlers/Programmer/Blogs/VeryBasics.html

    Übrigens in begründeten Ausnahmen macht mans durchaus, dass die SubObjekte Verweise auf ihre Owner halten - etwa TreeView-TreeNode, oder DataRows im Dataset oder sowas.
    Ist halt gelegentlich sinnvoll, aber immer erkauft durch eine "enge Kopplung" der Datentypen miteinander.