Search code examples
vb.netdatatabledatasetxmlwriter

Preserve Dataset row order XmlWriter vb


Trying to write some code to change the elements order in an XML file via a user interface. Quesiton being: how do I control the physical storage order elements are written in via WriteXML

For example, I want to transform:

<Image Name="Middle" file="Sauce.png" />
<Image Name="Top" file="Cheese.png" />
<Image Name="Bottom" file="PizzaBase.png" />

to:

<Image Name="Top" file="Cheese.png" />
<Image Name="Middle" file="Sauce.png" />
<Image Name="Bottom" file="PizzaBase.png" />

in the file. Approach so far:

.xml > dataset > datagridview (bound dataset.table)

This works great, allowing the user to move the row/element up and down. Any movement of a row is reflected in the Dataset.table when I view this in Locals (i.e. if "Cheese" is moved to the top in the DatagridView, it also sits at the top in the dataset).

However, when I come to write this back to the XML via XMLWriter, any moved rows get appended to the bottom of the xml, rather than in the same order of the dataset. For example, if I move "Cheese" up, then the output reads:

<Image Name="Middle" file="Sauce.png" />
<Image Name="Bottom" file="PizzaBase.png" />
<Image Name="Top" file="Cheese.png" />

Had a search around - couldn't find anything on this. Anyone have any ideas?


EDIT: This is how I'm re-ordering the rows:

 Private Sub _RigRowUp_Click(sender As Object, e As EventArgs) Handles _RigRowUp.Click
        If IsNothing(_RigImgsDGV.DataSource)
            Return
        End If
        Dim selectedRow As DataRow = _RigXMLImgsDS.Tables("Image").Rows(_RigImgsDGV.CurrentRow.Index)
        Dim selectedindex As Integer = _RigXMLImgsDS.Tables("Image").Rows.IndexOf(selectedRow)
        If selectedindex <= 0 Then
            Return
        End If
        Dim newRow As DataRow = _RigXMLImgsDS.Tables("Image").NewRow()
        newRow.ItemArray = selectedRow.ItemArray
        _RigXMLImgsDS.Tables("Image").Rows.Remove(selectedRow)
        _RigXMLImgsDS.Tables("Image").Rows.InsertAt(newRow, selectedindex - 1)
        _RigImgsDGV.ClearSelection()
        _RigImgsDGV.CurrentCell = _RigImgsDGV.Rows(selectedindex - 1).Cells(0)
        _RigImgsDGV.Rows(selectedindex - 1).Selected = True
    End Sub

_RigXMLImgsDS is the DataSet RigImgsDGV is the DataGridView

Bound within a public sub elsewhere via:

  _RigImgsDGV.DataSource = New BindingSource(_RigXMLImgsDS.Tables("Image"), Nothing)

Solution

  • Finally figured. You have to write the updated table from your dataset to a temporary table, then clear the table in the dataset, then write the rows of the temporary table one by one back to the matching table in the dataset. Code (with apologies as lifted straight from the full script, but should illustrate the process):

    Dim _tempDT As DataTable
        _tempDT = _RigXMLImgsDS.Tables("Image").Copy()
        _RigXMLImgsDS.Tables("Image").Clear()
        For Each DataRow In _tempDT.Rows
            _RigXMLImgsDS.Tables("Image").ImportRow(DataRow)
        Next
    

    Then use XMLWriter as usual. Thanks to Plutonix.