Simple XML (2/2)

Fortsetzung von Teil 1.

5. Speichern. Da wir ohne weiteres Zutun die Daten bereits bearbeiten können (der erste und einzigste vorhandene Datensatz wird bei Start der Applikation bereits angezeigt), fehlt noch eine Methode um die Veränderungen zurück in das XML-File zu speichern. Das geht genauso unkompliziert wie auch die Datenabholung:

_oDataSet.WriteXml(_sPATH_TO_XML_FILE)

Das ist alles. Nun packen wir das Ganze noch in eine eigene private Sub SaveData und platzieren ein Button auf das Formular der die Methode SaveData bei Klick aufruft.

6. Navigieren. Wir haben nun ein gebundenes Formular vorliegen. Was fehlt ist eine Navigation um auch durch die gelesenen Datensätze zu blättern. Hierzu brauchen wir zwei neue Button:
cmdForward, Text: „>“ und cmdBack, Text: „<“. Beide haben ein Klick-Ereignis.
Mit oben schon erwähnten DataBinding können wir nun in einem Kontext arbeiten, der uns die Navigation ebenfalls sehr einfach macht. Im Falle von cmdForward ist das

Me.BindingContext(_oDataTable).Position += 1

um einfach in den vorhandenen Datensätzen eine Position weiter zu springen und analog

Me.BindingContext(_oDataTable).Position -= 1

um eine Position zurückzugehen.

Das Beste ist: Sie brauchen sich keine Sorgen darüber zu machen, ob Sie über das „Ziel hinaus“ hinausschießen, also ob bsw die Position kleiner als 0 oder größer als die Anzahl der Datensätze wird. Das wird alles im BindingContext für Sie erledigt, sodass es tatsächlich bei den beiden Aufrufen bleiben kann.
Um zu dem letzen Datensatz zu springen, können Sie übrigens einfach

Me.BindingContext(_oDataTable).Position = Me.BindingContext(_oDataTable).Count

aufrufen.

7. Neuer Datensatz. Sehen wir uns nun an, wie man einen neuen Datensatz hinzufügen kann. Hierzu benötigen wir wieder einen neuen Button der mit „Add New“ betitelt wird und cmdAddNew benannt wird. Hierfür definieren wir das Klick-Ereignis:

Private Sub cmdAddNew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAddNew.Click
    Dim oDataRow As DataRow

    Me.txtInternalNumber.Text = Me.BindingContext(_oDataTable).Count + 1
    Me.txtTitle.Text = ""
    Me.txtInterpret.Text = ""

    oDataRow = _oDataTable.NewRow()
    With oDataRow
        .Item("InternalNumber") = Me.txtInternalNumber.Text
        .Item("Title") = Me.txtTitle.Text
        .Item("Interpret") = Me.txtInterpret.Text
    End With

    _oDataTable.Rows.Add(oDataRow)
    oDataRow = Nothing

    SaveData()

    Me.BindingContext(_oDataTable).Position = Me.BindingContext(_oDataTable).Count
End Sub

Da wir innerhalb unserer Datentabelle eine neue Zeile einfügen wollen, definieren wir uns zunächst eine neue DataRow. Diese Datarow initialisieren wir dann als neue Zeile (NewRow) und binden die einzelnen Controls an die jeweiligen Datenfelder (Item = Control.Text). Im weiteren Verlauf fügen wir die neue Datenzeile der Datentabelle zu (Rows.Add) und speichern die gesamte XML-Datei ab.
Um die Controls für die Aufnahme neuer Daten vorzubereiten, löschen wir vorher noch alle Eingaben in den Controls raus (Control.Text = „“) bzw. setzen die InternalNumber auf einen eindeutigen Wert. Diesen können wir, wie schon gesehen, ganz einfach aus dem BindingContext ermitteln. Da der Count, also die Anzahl der im BindingContext enthaltenen Elemente, gleich der Anzahl der CDs-Elemente in der XML-Datei entspricht, ist mit Sicherheit immer der folgende Ausdruck eindeutig:

Me.BindingContext(_oDataTable).Count + 1

Damit wir im Anschluß an diese „Vorbereitung zur Dateneingabe“ auch den Datensatz direkt bearbeiten können, springen wir noch mit der letzten Zeile der Methode zu dem eben angelegten Datensatz.

Ein weiterer positiver Seiteneffekt ist, dass wir (sofern wir keine Löschoperationen vornehmen oder das Control txtInternalNumber bearbeitbar lassen) dadurch eine durchängige, aufsteigende Nummerierung aller CDs erhalten.

Da wir schon einen Save-Button auf dem Formular realisiert haben, können wir nun die Applikation starten, den Button „Add New“ drücken, neue Daten eingeben und mit „Save“ die Daten speichern. Ein Blick ins XML-File bestätigt das.

8. Filtern. Um unsere eingangs postulierte Funktionspalette zu komplettieren benötigen wir nun noch einen Filter. In unserem einfachen Beispiel für eine kleine Statistik.
Wir wollen uns nun noch anzeigen lassen, wie viele CDs wir besitzen, in denen der Interpret gleich „Counting Crows“ ist.
Hierzu müssen wir nur die Datentabelle nach unseren gewünschten Kriterien selektieren. Also als Beispiel:

_oDataTable.Select(„Interpret = ‚Counting Crows’“)

Als Rückgabewert dieser Funktion erhalten wir ein Array von DataRows, können also mit der Length-Methode direkt auf die Anzahl der gefilterten Zeilen zugreifen.

Ergebnis. XML ist wirklich einfach, jedenfalls in den grundsätzlichen Funktionen kommt man mit wenigen Zeilen aus um ein einfaches Programm mit XML-Unterstützung zu kreieren. Die (manuelle) Datenbindung ist da ebenso einfach und ermöglicht vielerlei schöne Möglichkeiten. Man denke da nur an die Möglichkeit statt Daten an die „Text“-Eigenschaft an andere Eigenschaften zu binden…

Anmerkung. Dieses Beispiel funktioniert übrigens auch im Compact Framework also bsw als Windows Mobile Programm. Hierbei ist lediglich eine kleine Änderung nötig um den Pfad zum Daten-XML-File herauszufinden. Siehe hierzu das Posting “Pfad der aktuellen Anwendung ermitteln”.

Das Beispiel-Projekt für VS2005 könnt ihr hier herunterladen.