Problem mit DataGridView und XML Laden/Speichern

  • VB.NET
  • .NET 4.5

Es gibt 34 Antworten in diesem Thema. Der letzte Beitrag () ist von Yanbel.

    Problem mit DataGridView und XML Laden/Speichern

    Hallo,

    ich habe ein Problem, ich habe ein Tool erstellt, welches Daten in XML Speichern soll, diese "Daten" sollen in einen DataGridView geladen werden, Änderungen gespeichert werden.. Die xml Datei soll eigentlich ins Programmverzeichnis erstellt/geladen werden.. (Was auch nicht Klappt)
    Wenn ich den Code, ausführe bekomme ich beim Laden und oder Speichern den Fehler das das Stammelement nicht gefunden wird. Und das die Datei gerade von einen anderen Prozess verwendet wird. (Mit XML hab ich noch nie gearbeitet..) HILFE..

    An bei der Code den ich bis her habe..

    VB.NET-Quellcode

    1. Public Class Form2
    2. Dim dt As New DataTable
    3. Dim filestream As IO.FileStream
    4. Const xmldaten As String = "C:\Temp\passwortliste.xml"
    5. Private Sub CreateData()
    6. With dt
    7. .TableName = "testdaten"
    8. .Columns.Add("ID")
    9. .Columns.Add("Account")
    10. .Columns.Add("WebseitenURL")
    11. .Columns.Add("Benutzername")
    12. .Columns.Add("Passwort")
    13. .PrimaryKey = { .Columns("ID")}
    14. End With
    15. dt.WriteXml(xmldaten, XmlWriteMode.WriteSchema)
    16. End Sub
    17. Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    18. If Not IO.File.Exists(xmldaten) Then CreateData()
    19. End Sub
    20. Private Sub Btnload_Click(sender As Object, e As System.EventArgs) Handles Btnload.Click
    21. Try
    22. dt.Clear()
    23. dt.ReadXml(xmldaten)
    24. dt.AcceptChanges()
    25. dgv.DataSource = dt
    26. Catch ex As Exception
    27. MsgBox(ex.Message)
    28. End Try
    29. End Sub
    30. Private Sub BtnSave_Click(sender As Object, e As System.EventArgs) Handles Btnsave.Click
    31. Try
    32. If Not Writexmltofile() Then
    33. If MsgBox("Änderungen konnten nicht gespeichert werden." &
    34. vbCrLf &
    35. "Trotzdem speichern?",
    36. MsgBoxStyle.Exclamation Or MsgBoxStyle.OkCancel) =
    37. MsgBoxResult.Cancel Then Exit Sub
    38. dt.WriteXml(xmldaten, 0)
    39. End If
    40. Catch ex As Exception
    41. MsgBox(ex.Message)
    42. End Try
    43. End Sub
    44. Public Function Writexmltofile() As Boolean
    45. Dim fs As IO.FileStream = IO.File.Open(xmldaten, IO.FileMode.Open, IO.FileAccess.ReadWrite, IO.FileShare.Read)
    46. Dim dt_current As New DataTable
    47. dt_current.ReadXml(fs)
    48. With dt_current
    49. If .Columns.Count <> dt.Columns.Count Then Return False
    50. For c As Integer = 0 To .Columns.Count - 1
    51. If Not dt.Columns.IndexOf(.Columns(c).ColumnName) = c Then
    52. fs.Close() 'Spaltenschema inzwischen geändert
    53. Return False
    54. End If
    55. Next c
    56. Dim pcn As String = dt.PrimaryKey(0).ColumnName
    57. For r As Integer = 0 To .Rows.Count - 1
    58. Dim row_user As DataRow =
    59. dt.Rows.Find(.Rows(r)(pcn))
    60. If row_user IsNot Nothing Then
    61. For c As Integer = 0 To .Columns.Count - 1
    62. Dim cc As Integer =
    63. dt.Columns.IndexOf(.Columns(c).ColumnName)
    64. If Not .Rows(r)(c).Equals _
    65. (row_user(cc, DataRowVersion.Original)) Then
    66. fs.Close() 'Zeileninhalt inzwischen extern geändert
    67. Return False
    68. End If
    69. If Not row_user.RowState = DataRowState.Unchanged Then
    70. .Rows(r)(c) = row_user(cc, DataRowVersion.Current)
    71. End If
    72. Next c
    73. Else
    74. fs.Close() : Return False
    75. End If
    76. Next r
    77. For r As Integer = 0 To dt.Rows.Count - 1
    78. If dt.Rows(r).RowState = DataRowState.Added Then
    79. .Rows.Add(dt.Rows(r).ItemArray)
    80. End If
    81. Next r
    82. fs.Close()
    83. .WriteXml(xmldaten, XmlWriteMode.WriteSchema)
    84. dt.AcceptChanges()
    85. End With
    86. Return True
    87. End Function

    Für jede Hilfe bin ich Dankbar. :)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Andy2002“ ()

    @Andy2002 Deine Herangehensweise ist falsch.
    Erstell eine DataTable und binde die als DataSource an das DGV.
    Schau Dir mal dies an:
    Differenz in Prozent ausrechnen
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    1. bitte CodeTags verwenden
    2. Der Code stammt wohl aus dem vb@archiv (da hat sich sogar @ErfinderDesRades am Thread mit beteiligt) - das ist insofern wichtig, weil wir dann anders Deine Fähigkeiten einschätzen können. Wär das nicht klar gewesen, dass der Code von woanders her kommt, hätten wir dauernd irgendwelche Fragen gestellt, warum Du dies und das so gemacht hast und effektiv hättest Du uns gar nichts dazu sagen können.
    3. Probier es mal ohne VB6-Namespace, siehe empfohlene VS-Einstellungen
    4. Bei mir funktioniert der Code - auch wenn er meinen Augen schmerzt. Ich musste nur den Pfad ändern, indem ich von "C:\Temp\passwortliste.xml" auf "passwortliste.xml" umgestellt habe und es somit im Projektverzeichnis abspeichere.

    ##########

    RodFromGermany schrieb:

    Erstell eine DataTable und binde die als DataSource an das DGV.
    Macht er doch. Zeile#3, ab #9, #32
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Ja teile davon sind aus dem Forum, andere teile selbst geschrieben, andere teile aus dem Visual Basic Buch, uvm..

    Also wenn ich auf Option Strict On setze, kann ich nicht Speichern.
    Mache ich off, dann erstellt er beim Laden immer neue Columns, und läd nicht den Inhalt..
    hmm

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Andy2002“ ()

    Andy2002 schrieb:

    wenn ich auf Option Strict On setze, kann ich nicht Speichern.
    Was'n das für ne Aussage? Der Code ist Option Strict On-"kompatibel". Wenn Du es dazuschalten würdest, würde der Compiler zur Designzeit (also während des Programmschreibens) Fehler anmeckern, falls welche vorhanden sind. Aber zur Laufzeit (wenn Du das Programm startest) gäbe es keinen Unterschied. Daher kann Deine Aussage so nicht den Tatsachen entsprechen.
    Zum anderen: Entfern den Mist von Try-Catch, denn: Fange nur Exceptions ab, die Du kennst und sinnvoll bearbeiten kannst.
    Und wenn dann irgendwelche Exceptions kommen, dann poste deren genauer Wortlaut und wir können sicherlich weiterhelfen. Aber durch diese Sinnloskonstrukte verhinderst Du sinnvolle Fehlermeldungsoptionen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    VaporiZed schrieb:

    Entfern den Mist von Try-Catch
    Das heißt: Alles, was im Try-Bereich ist beibehalten, das Try und alles von Catch bis End Try raus. Du zeigst einen Screenshot einer MessageBox. Und das sagt mir, dass Du den Kram noch drin hast. Das ist vermutlich beim Speichern aufgetreten, oder?
    Dann mach mal erstmal folgendes:
    Lösch die passwortliste.xml im von Dir geposteten Verzeichnis.

    Das hier

    VB.NET-Quellcode

    1. Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    2. If Not IO.File.Exists(xmldaten) Then CreateData()
    3. End Sub

    ersetzt Du durch

    VB.NET-Quellcode

    1. Private Sub Form2_Shown(sender As Object, e As EventArgs) Handles Me.Shown
    2. If Not IO.File.Exists(xmldaten) Then CreateData()
    3. End Sub

    Und zwar, weil Exceptions im FormLoad-EventHandler beim Debuggen gern verschluckt werden. Hatte ich neulich erst, als ne LINQ-Abfrage scheiterte, aber das beim Debuggen nicht angezeigt wurde, sondern erst in der fertigen Exe. Hat mich sinnlos Zeit gekostet, den Fehler zu finden. Das Beheben war hingegen schnell.

    In der Laden-Sub schmeißt Du das Try-Catch weg, damit wir sehen, was abgeht.

    Und

    VB.NET-Quellcode

    1. Try
    2. If Not Writexmltofile() Then
    3. If MsgBox("Änderungen konnten nicht gespeichert werden." &
    4. vbCrLf &
    5. "Trotzdem speichern?",
    6. MsgBoxStyle.Exclamation Or MsgBoxStyle.OkCancel) =
    7. MsgBoxResult.Cancel Then Exit Sub
    8. dt.WriteXml(xmldaten, 0)
    9. End If
    10. Catch ex As Exception
    11. MsgBox(ex.Message)
    12. End Try

    ersetzt Du durch

    VB.NET-Quellcode

    1. dt.WriteXml(xmldaten)

    in der Speichern-Sub.

    Und dann schauen wir nochmal.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Jou.

    Andy2002 schrieb:

    VB.NET-Quellcode

    1. Dim fs As IO.FileStream = IO.File.Open(xmldaten, IO.FileMode.Open, IO.FileAccess.ReadWrite, IO.FileShare.Read)
    2. ' ...
    3. fs.Close()

    Das ganze packst Du in einen Using-Block.
    docs.microsoft.com/de-de/dotne…tatements/using-statement
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    @Andy2002 Verstehe die Meldung. ;)

    VB.NET-Quellcode

    1. Dim dt = New DataTable()
    machst Du

    VB.NET-Quellcode

    1. Dim dt = New DataTable("Name der Tabelle")
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    Wo soll das hin??

    VB.NET-Quellcode

    1. ​Dim dt = New DataTable("Name der Tabelle")


    Sie wird doch hier benannt..

    VB.NET-Quellcode

    1. ​Private Sub CreateData()
    2. With dt
    3. .TableName = "testdaten"
    4. .Columns.Add("ID")
    5. .Columns.Add("Account")
    6. .Columns.Add("WebseitenURL")
    7. .Columns.Add("Benutzername")
    8. .Columns.Add("Passwort")
    9. .PrimaryKey = { .Columns("ID")}
    10. End With
    11. dt.WriteXml(xmldaten, XmlWriteMode.WriteSchema)
    12. End Sub


    Und auch hier wird Ja eine Tabelle direkt benannt..

    VB.NET-Quellcode

    1. ​Public Function Writexmltofile() As Boolean
    2. 'aktuelle Daten neu lesen und sperren
    3. Dim fs As IO.FileStream = IO.File.Open(xmldaten, IO.FileMode.Open, IO.FileAccess.ReadWrite, IO.FileShare.Read)
    4. Dim dt_current As New DataTable
    5. dt_current.ReadXml(fs)
    6. 'aktuelle Daten abgleichen
    7. With dt_current
    8. If .Columns.Count <> dt.Columns.Count Then Return False
    9. For c As Integer = 0 To .Columns.Count - 1
    10. If Not dt.Columns.IndexOf(.Columns(c).ColumnName) = c Then
    11. fs.Close() 'Spaltenschema inzwischen geändert
    12. Return False
    13. End If
    14. Next c
    15. Dim pcn As String = dt.PrimaryKey(0).ColumnName
    16. For r As Integer = 0 To .Rows.Count - 1
    17. Dim row_user As DataRow =
    18. dt.Rows.Find(.Rows(r)(pcn))
    19. If row_user IsNot Nothing Then
    20. For c As Integer = 0 To .Columns.Count - 1
    21. Dim cc As Integer =
    22. dt.Columns.IndexOf(.Columns(c).ColumnName)
    23. If Not .Rows(r)(c).Equals _
    24. (row_user(cc, DataRowVersion.Original)) Then
    25. fs.Close() 'Zeileninhalt inzwischen extern geändert
    26. Return False
    27. End If
    28. If Not row_user.RowState = DataRowState.Unchanged Then
    29. 'geänderten Wert in frisch geladene Table übertragen
    30. .Rows(r)(c) = row_user(cc, DataRowVersion.Current)
    31. End If
    32. Next c
    33. Else
    34. fs.Close() : Return False 'Schlüssel geändert oder
    35. 'inzwischen neue Zeile erstellt
    36. End If
    37. Next r
    38. For r As Integer = 0 To dt.Rows.Count - 1
    39. If dt.Rows(r).RowState = DataRowState.Added Then
    40. .Rows.Add(dt.Rows(r).ItemArray) 'neu erstellte Zeile anfügen
    41. End If
    42. Next r
    43. fs.Close()
    44. .WriteXml(xmldaten, XmlWriteMode.WriteSchema)
    45. dt.AcceptChanges()
    46. End With
    47. Return True
    48. End Function

    Andy2002 schrieb:

    Und auch hier wird Ja eine Tabelle direkt benannt..
    Hier?

    Andy2002 schrieb:

    VB.NET-Quellcode

    1. Dim dt_current As New DataTable
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    Wenn die Exception kommt, fahr mit der Maus über dt und lass Dir den Inhalt anzeigen. Vielleicht zeigt sich ja, dass die dt doch noch nicht initialisiert wurde. Kannst Du dt mal "aufklappen" und nen Screenshot schicken? Also sowas:

    Du hast Post#8 noch nicht ganz beachtet, siehe dort die letzten beiden Codeblöcke.

    ##########

    Wenn in der writexmltofile die Datei ausgelesen wird und dadurch die ganzen Daten der DataTable gesetzt werden, dann hast Du ein Problem, wenn der XML-Inhalt geschrottet wurde, weil dann das Auslesen murks ergibt. Daher solltest Du diese Sub nicht verwenden, sondern einfach nur dt.WriteXML(DeinDateipfad). Denn solange Du nicht genau weißt, was in der Sub passiert, solltest Du sie nicht verwenden.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Also ich habe jetzt keinen Fehler mehr wenn ich Speichern drücke. Aber die Datei die erstellt wird (passwortliste.xml) hat nun keinen Inhalt.. Es steht nur:

    XML-Quellcode

    1. <?xml version="1.0" encoding="ISO-8859-1"?><DocumentElement/>
    Im Dokument..

    Ich habe Folgendes gemacht..

    VB.NET-Quellcode

    1. Dim dt = New DataTable("testdaten")


    Die Function writexmltofile hab ich jetzt raus genommen, trotzdem wird mir kein Inhalt erzeugt..

    VB.NET-Quellcode

    1. Public Class Form2
    2. Dim dt As New DataTable("testdaten")
    3. Dim filestream As IO.FileStream
    4. Const xmldaten As String = "passwortliste.xml"
    5. Private Sub CreateData()
    6. With dt
    7. .TableName = "testdaten"
    8. .Columns.Add("ID")
    9. .Columns.Add("Account")
    10. .Columns.Add("WebseitenURL")
    11. .Columns.Add("Benutzername")
    12. .Columns.Add("Passwort")
    13. .PrimaryKey = { .Columns("ID")}
    14. End With
    15. dt.WriteXml(xmldaten, XmlWriteMode.WriteSchema)
    16. End Sub
    17. Private Sub Form2_Shown(sender As Object, e As EventArgs) Handles Me.Shown
    18. If Not IO.File.Exists(xmldaten) Then CreateData()
    19. End Sub
    20. Private Sub Btnload_Click(sender As Object, e As System.EventArgs) Handles Btnload.Click
    21. 'dt.Clear()
    22. dt.ReadXml(xmldaten)
    23. dt.AcceptChanges()
    24. dgv.DataSource = dt
    25. End Sub
    26. Private Sub BtnSave_Click(sender As Object, e As System.EventArgs) Handles Btnsave.Click
    27. dt.WriteXml(xmldaten)
    28. End Sub​

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Andy2002“ ()

    Andy2002 schrieb:

    trotzdem wird mir kein Inhalt erzeugt
    Wieso erzeugt? Reinschreiben ins DGV musst Du schon selber. Nur zur Sicherheit: da irgendwas Inhaltliches erzeugen hat der Erstcode auch nicht gemacht.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Andy2002 schrieb:

    trotzdem wird mir kein Inhalt erzeugt..
    In Post #2 hab ich Dir einen Link zu einem funktionierenden Beispiel gepostet.
    Lesen bildet. Testen auch.
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    Ja ich Schreibe die Daten in die dgv über das Programm rein.. Also in jede Spalte der Zeile steht was.. Dann klicke ich auf den Button btnsave, -> Die Passwortliste.xml wird erstellt.. (Ist jedoch leer!) Und Laden klappt so auch nicht.
    @Andy2002 Hast Du das Beispiel von Post #2 mal angesehen und laufen lassen?
    Offensichtlich nicht.
    Das sieht mir doch stark nach Beratungsresistenz aus.
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    Moooment mal. Schreibst Du in die erste Zeile rein und während Du noch in der 1. Zeile bist, drückst Du auf [Speichern]? Dann schau doch mal bitte, was in der DataTable konkret drin steht. Denn wenn Du die 1. Zeile nicht verlässt, werden die Änderungen nicht in die DataTable übernommen. Aber halt. Ich hab Dich ja schon gebeten, einen DataTableContent zu posten. Und: Wenn Du die DataTable gespeichert hast, was steht dann in der Datei? Du könntest noch Dein Projekt per [+Erweiterte Antwort] posten, vielleicht ist so der Fehler zu finden.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.