Alternative zu Dataset ? (Notizbuch)

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

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

    Eine einfache xml-File reicht ebenfalls. Wenn man nicht mit DataSets arbeiten möchte kann man auch objektorientiert Programmieren und die Objekte serialisieren.

    Aber so wie es aussieht, war die Ablehnung der DataSets ja nur auf ein paar Verständnisproblemen zurück zu führen. Bei Win Forms ist es im Endeffekt auch die pflegeleichteste Lösung.
    Option strict = on

    If it's stupid and it works it ain't stupid.

    asusdk schrieb:

    und funktionieren tut jetzt leider auch nicht mehr als davor
    Dochdoch - mein Werk funzt sehr anders.
    Beachte den ParentChild-View mit angeschlossenem DetailView - also die Controls auf Form1 machen bei meiner Version ihren Job, bei deiner nicht.
    Bisserl doof, dass ich jetzt deine Benamte Solution noch einmal fixen muss... :(
    So, jetzt hübsch gemacht:
    • Option Strict On gestellt - siehe Visual Studio - Empfohlene Einstellungen
    • ca. 30 unnütze GeneralImporte aus den Projekteinstellungen entfernt - siehe Visual Studio - Empfohlene Einstellungen
    • das Dataset aussm MyProject-Ordner in den Projekt-Ordner verschoben - in MyProject hats nix verloren, und ist dort auch kaum je zu finden.
    • Den Space aus dem Projekt-Namen entfernt - der sorgte nämlich dafür, dass der Form-Designer die Forms nicht anzeigen konnte.
    • Unnütze Regions rausgeworfen - Code ist zum Lesen da, nicht zum Verstecken!
    • Private Dinge auch Private deklariert
    • dem MainForm ein anständiges, resizeables Layout verpasst - s. Layout in Windows.Forms
    • die Daten-Datei ins Projekt mit aufgenommen
    • Bindingsources kurz und knapp und klar benamt (soweit als möglich: was will man bei TabellenNamen wie HDDTC und HDDTN auch machen?)
    • erwünschte Funktionalität hingebastelt
    • Ein Menü mit Buttons zum Laden und Speichern
    Jo - sieht nun so aus:

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Imports System.Windows.Forms
    3. Public Class frmHDNotes
    4. Private _db As String = System.IO.Path.GetFullPath("..\..\db.xml")
    5. Private Sub Form_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    6. loadDB()
    7. End Sub
    8. Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
    9. saveDB()
    10. End Sub
    11. Private Sub loadDB()
    12. HDDS.Clear()
    13. If IO.File.Exists(_db) Then HDDS.ReadXml(_db)
    14. End Sub
    15. Private Sub saveDB()
    16. Me.Validate()
    17. HDDS.WriteXml(_db)
    18. End Sub
    19. Private Sub Button_Click(sender As Object, e As EventArgs) Handles btLoad.Click, btSave.Click, btn_EditNote.Click, btn_DeleteNote.Click, btn_AddNote.Click, btn_editCategory.Click, btn_deleteCategory.Click, btn_AddCategory.Click
    20. Select Case True
    21. Case sender Is btLoad : loadDB()
    22. Case sender Is btSave : saveDB()
    23. Case sender Is btn_DeleteNote : bsTC_TN.RemoveCurrent()
    24. Case sender Is btn_deleteCategory : bsTC.RemoveCurrent()
    25. Case sender Is btn_EditNote
    26. Using frmAddNote As New frmNewOrEditNote
    27. frmAddNote.bsTN.DataSource = bsTC_TN.Current
    28. If frmAddNote.ShowDialog(Me) = DialogResult.OK Then bsTC.EndEdit()
    29. End Using
    30. Case sender Is btn_AddNote
    31. Using frmAddNote As New frmNewOrEditNote
    32. frmAddNote.bsTN.DataSource = bsTC_TN.AddNew()
    33. If frmAddNote.ShowDialog(Me) = DialogResult.OK Then bsTC.EndEdit()
    34. End Using
    35. Case sender Is btn_editCategory
    36. Using frmAddCategory As New frmNewOrEditCategory
    37. frmAddCategory.bsTC.DataSource = Me.bsTC.Current
    38. If frmAddCategory.ShowDialog(Me) = DialogResult.OK Then bsTC.EndEdit()
    39. End Using
    40. Case sender Is btn_AddCategory
    41. Using frmAddCategory As New frmNewOrEditCategory
    42. frmAddCategory.bsTC.DataSource = Me.bsTC.AddNew()
    43. If frmAddCategory.ShowDialog(Me) = DialogResult.OK Then bsTC.EndEdit()
    44. End Using
    45. End Select
    46. End Sub
    47. End Class
    Mehr muss der Frosch nicht kosten :D
    Dateien
    • HD_Notes01.zip

      (30,41 kB, 156 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „ErfinderDesRades“ ()

    @ErfinderDesRades

    Funktioniert einwandfrei, echt klasse ! Danke dir, aber einige Fragen drängen sich mir da noch auf :

    "ca. 30 unnütze GeneralImporte aus den Projekteinstellungen entfernt - siehe Visual Studio - Empfohlene Einstellungen"
    macht es denn irgendwelche Probleme, wenn ich die Importe drinn lasse ? denn bisher ist es so durchaus sehr praktisch wenn diese bereits "dabei" sind

    "das Dataset aussm MyProject-Ordner in den Projekt-Ordner verschoben - in MyProject hats nix verloren, und ist dort auch kaum je zu finden."
    ich wusste nicht das ich das irgendwie steuern kann ? um das Dataset zu erstellen geht man doch auf Projekt>hinzufügen>Dataset, wo genau dieses dann Liegt kann ich dabei doch nicht beeinflussen,
    und wenn das so hinzugefügt wurde gibts es dabei irgendwelche Probleme ?

    "Den Space aus dem Projekt-Namen entfernt - der sorgte nämlich dafür, dass der Form-Designer die Forms nicht anzeigen konnte."
    Selbst ohne das Leerzeichen kann er diese nicht anzeigen wenn der Ordner an einem neuen Ort geöffnet wird, erst wenn dann eine Form geöffnet wurde, man das Projekt schliesst und wieder öffnet lädt er die Formen auch direkt
    genau wie mit leerzeichen, oder verstehe ich das was du meintest hier falsch ?

    "Unnütze Regions rausgeworfen - Code ist zum Lesen da, nicht zum Verstecken!"
    habe ich jetzt für die neue Vorlage auch so gemacht, war wohl eine Schnappsidee

    "Private Dinge auch Private deklariert"
    Macht das denn einen Großen und/oder wichtigen Unterschied ?

    LG

    p.S. Option Strict hatte ich in der Vorlage glatt vergessen, ist in der neuen Vorlage auch gleich aktiviert
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If

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

    asusdk schrieb:


    "ca. 30 unnütze GeneralImporte aus den Projekteinstellungen entfernt - siehe Visual Studio - Empfohlene Einstellungen"
    macht es denn irgendwelche Probleme, wenn ich die Importe drinn lasse ? denn bisher ist es so durchaus sehr praktisch wenn diese bereits "dabei" sind
    Ich bin Anhänger zweier Prinzipien:
    1. Was ich nicht brauche - weg damit
    2. Was ich nicht kenne, brauche ich schoma garnet - erst recht weg damit
    Daraus ergibt sich Code, den ich verstehe, und wo ich weiss, was da passiert.
    Auch unnütze Dll-Verweise gehören entfernt - habich jetzt bei dir nicht geguckt, aber bestimmt hast du allerlei INet-Kram eingebunden, den du ühaupt nicht brauchst, und der evtl. die Exe nur aufbläht.
    Am Wichtigsten ist vlt., dass ein Namespace-Import - sei er nun Generell oder auf Datei-Ebene - wie der Name "Namespace" schon sagt, den "Namensraum" erweitert.
    Daraufhin liefert Intellisense mehr Angebote, und logischerweise lauter unnützes Zeug.
    Verheerend ist das mittm Microsoft.Visualbasic-Namespace, da liefert Intellisense dann lauter Vb6-Gerümpel an, dass ein vb6-Umsteiger sich kaum je weiterentwickelt, und für immer Anfänger bleibt.
    Aber auch System.Collections ist schädlich, da fährt zB die ArrayLIst herum, eine untypisierte Auflistung, die man seit 2005 nicht mehr braucht.
    Ansonsten sind die meisten Namespaces nicht soo schlimm - wie gesagt, mein Prinzip: Code nur, was du verstehst, und das andere code nicht.
    Und bei 30 unnützen GeneralImporten wirds aber wirklich bisserl absurd.

    "das Dataset aussm MyProject-Ordner in den Projekt-Ordner verschoben - in MyProject hats nix verloren, und ist dort auch kaum je zu finden."
    ich wusste nicht das ich das irgendwie steuern kann ? um das Dataset zu erstellen geht man doch auf Projekt>hinzufügen>Dataset, wo genau dieses dann Liegt kann ich dabei doch nicht beeinflussen,
    und wenn das so hinzugefügt wurde gibts es dabei irgendwelche Probleme ?
    Normalerweise landet ein Dataset dann da, wo ichs jetzt hingemacht hab.
    Wie gesagt: Wie du das geschafft hast, es unter die verborgenen Dateien des MyProject-Ordners zu bugsieren ist mir schleierhaft.
    Und natürlich kannst du den Speicherort jeder Datei beeinflussen: Einfach im SolutionExplorer mit Drag&Drop dahin ziehen, wo du sie haben willst.
    Der SolutionExplorer kann auch UnterOrdner erstellen und löschen und pipapo - also in grösseren Projekten ists oft sehr geraten, sich eine sinnige Ordnerstruktur auszudenken (etwa UI, BL, DataAccess, oder so).

    "Den Space aus dem Projekt-Namen entfernt - der sorgte nämlich dafür, dass der Form-Designer die Forms nicht anzeigen konnte."
    Selbst ohne das Leerzeichen kann er diese nicht anzeigen wenn der Ordner an einem neuen Ort geöffnet wird, erst wenn dann eine Form geöffnet wurde, man das Projekt schliesst und wieder öffnet lädt er die Formen auch direkt
    genau wie mit leerzeichen, oder verstehe ich das was du meintest hier falsch ?
    Jaja, oft hilft kompilieren.
    Aber bei mir hulf es eben nicht, der Designer hats einfach nicht gebacken gekriegt.
    Meine Empfehlung: Beim Programmieren alles "konservativ" benamen, also keine Spaces, Umlaute, Sonderzeichen in Dateinamen, Ordnern, Klassen-Namen.

    "Private Dinge auch Private deklariert"
    Macht das denn einen Großen und/oder wichtigen Unterschied ?
    Es gilt das Prinzip "Kapselung".
    Eine Klasse soll nur das an die Öffentlichkeit veröffentlichen, was nötig ist, um mit der Klasse zu arbeiten.
    Je weniger Public veröffentlicht ist, desto weniger Schindluder kann getrieben werden.
    Auch ist solch Code leichter verständlich, weil an den Public Membern einer Klasse erkenne ich, wie und wozu sie zu gebrauchen ist.
    Eine Public SaveData-Methode kann evtl. Sinn machen. In einem Form ist eine Public SaveData, die wirklich benutzt wird, aber meist ein Designfehler.
    Deshalb muss ich sowas untersuchen, wenn darauf stosse.
    Womit wir wieder beim sinnlosen Code sind, der einfach immer enorm Man-Power frisst, wenn jemand ihn verstehen will.
    Ok, gut zu wissen, dann werde ich einige der Importe wohl am besten entfernen, was das DataSet angeht, ich habe da nichts geändert, also wird es wohl vom Studio dahingepackt worden sein, aus welchen gründen auch immer ^^
    gut das mit Private/Public macht mit dieser Erklärung durchaus Sinn, danke dir vielfach^^
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If

    asusdk schrieb:

    Option Strict hatte ich in der Vorlage glatt vergessen, ist in der neuen Vorlage auch gleich aktiviert

    Setze doch Option Strict On in der IDE, als Standard, dann bist du auf der sicheren Seite.
    Visual Studio - Empfohlene Einstellungen
    Im Video wird gezeigt, wo sich die Einstellung befindet und mehr.
    @ErfinderDesRades
    Sorry das ich dich nochmal stören muss aber ich habe noch eine Frage zu deinem Tutorial : Daten laden, speichern, verarbeiten - einfachste Variante
    du verwendest hierbei in der Suche folgende Function:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Function FindPerson(pattern As String) As Boolean
    2. For i = 0 To Me.PersonBindingSource.Count - 1
    3. Dim person = DirectCast(DirectCast(PersonBindingSource(i), DataRowView).Row, PersonRow)
    4. If person.Name Like pattern Then
    5. PersonBindingSource.Position = i
    6. Return True
    7. End If
    8. Next
    9. Return False
    10. End Function

    aber wie kommst du hier bei der Zeile : Dim person = DirectCast(DirectCast(PersonBindingSource(i), DataRowView).Row, PersonRow)
    am Ende auf PersonRow ?

    Denn wenn ich den Code zum füllern einer Combobox verwenden Möchte, unterstreichet er mir in folgendem Beispiel "CategoryNameRow" und saagt es sei nicht definiert.

    For i = 0 To Dt_NoticesBindingSource.Count - 1
    Dim CATEGORY = DirectCast(DirectCast(Dt_NoticesBindingSource(i), DataRowView).Row, CategoryNameRow)
    ComboBox1.Items.Add(CATEGORY)
    Next
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If
    Naja, in meim Dataset gibts eine Tabelle Person, also gibts auch die Klasse PersonRow.

    Du hast diese Tabelle nicht, also gibts diese Klassen bei dir auch nicht - sie "ist nicht definiert", wie der Compiler es ausdrückt.
    Eine Tabelle CategoryName hast du scheints auch nicht, weil sonst gäbe es ja die Klasse CategoryNameRow.

    Guck in dein Dataset nach, wie deine Tabellen heissen, dann weisst du auch, wie die Rows heissen, die bei dir definiert sind.

    Vielleicht verfällst du dann ja sogar auf die Idee, den Tabellen sinnvollere Namen zu verleihen - weisst ja: mit vernünftiger Benamung wird Code viel leichter verständlich.
    Nur beim Umbenennen musste aufpassen - am besten Projekt-Backup machen.
    Weil es sind schon Bindings gesetzt auf die alten Namen, und wenn du die TabellenNamen änderst, musstese auch in den Bindings ändern.
    Evtl lieber die projektweite Volltextsuche nehmen statt im Dataset-Designer.

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

    habe es gelöst bekommen, musste vor der Row noch das DataSet angeben

    Spoiler anzeigen

    VB.NET-Quellcode

    1. For i = 0 To Dt_NoticesBindingSource.Count - 1
    2. Dim CATEGORY = DirectCast(DirectCast(Dt_NoticesBindingSource(i), DataRowView).Row, ds_HDNotices.dt_NoticesRow)
    3. ComboBox1.Items.Add(CATEGORY.CategoryName)
    4. Next


    so funktioniert die Funktion,
    leider hilft mir diese nicht weiter, da er dennoch nur die eine category anzeigt, welche in der Bindingsource ausgewählt ist, und leider nicht alle, so das ich quasi beim anlegen einer neuen Notiz die zugehörige Category noch wählen könnte

    ebenso suche ich noch eine Möglichkeit bei Kategorie, Quasi eine Alle-Kategorie anzulegen, so dass er dann die Notices eben alle anzeigt, aber auch hier finde ich nicht mal einen Ansatz, ich vermute das ich bei verwendung eines Datasets wohl auf derartige Comfortfunktionen verzichten müsste ?
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If

    asusdk schrieb:

    habe es gelöst bekommen, musste vor der Row noch das DataSet angeben
    Wennde in mein Tut-Code guckst, wirste feststellen, dass ich den Dataset-Typ als Datei-Import importiere.

    Ansonsten braucht man im NotizEdit-Dialog die Kategorie nicht auswählen - jdfs nicht in dem Sample, was ich gemacht hab.
    Weil die Kategorie ist ja bereits im MainForm gewählt, und wenn du eine Notiz einer anneren Kategorie zuordnen willst, dann wähl bitte diese Kategorie vorher auch an.

    Weil das gibt ein verwirrendes Verhalten, wenn du Kategorie1 anguckst mit allen deren Notizen, dann aber eine Notiz für Kategorie2 zufügst.
    Weil das zugefügte siehste erstmal nicht, weil du guckst ja Kategorie1 an.

    Keine gut Useability.
    Ja Stimmt macht sinn ^^ (Das es in deinem Beispiel nicht mit angezeigt wird ist mir bewusst, ich versuche ja gerade anhand deines Musters selbst ein wenig durchzusteigen und arbeite an einer eigenen version bei der ich mich an deiner orientiere ^^)

    Aber eine letzte Frage noch kann man es irgendwie bewerkstelligen, das man Eine Generalkategorie anlegen kann bei der wenn ich diese wähle, alle Notizen angezeigt werden, also quasi alle notizen unabhängig der zugehörigen Kategorie ?
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If
    Das geht nicht mit einer GeneralKategorie, sondern um die Notizen Kategorie-unabhängig anzuzeigen müssteste eine annere BindingSource nehmen.
    Eine, deren DataSource nicht bsCategory ist, sondern die direkt an der CategoryTabelle hängt.
    Oder die bestehende BindingSource nehmen, und deren Binding-Eigenschaften abändern.



    Übrigens, eine Combobox befüll bitte nicht mit .Items.Add(), sondern erschaff auch für die Combo eine BindingSource, und häng die Combo da dran.
    Übrigens, eine Combobox befüll bitte nicht mit .Items.Add(), sondern erschaff auch für die Combo eine BindingSource, und häng die Combo da dran.

    Ja das hatte ich ja ursprünglich, da zeigte er mir aber eben nur die eine gewählte an, nicht wie anfangs gedacht alle kategirien, daher gab es ja den versuch ^^
    If Energy = Low Then
    Drink(aHugeCoffee)
    Else
    Drink(aHugeCoffeeToo)
    End If