2016-08-15 2 views
0

Ich versuche, XML-Zeichenfolge von und zu einem DataGridView zu speichern und zu laden.
Mit folgendem Code kann ich das tun, aber die Datentypen der Spalten sind verloren und das ganze Gitter wird dann nur mit Strings gefüllt. In dieser Situation funktionieren Formatierung und Sortierung nicht mehr.DataGridView in XML mit beibehaltenen Datentypen

Ist hier etwas, was ich tun kann, um Originaldatentypen während des gezeigten Prozesses zu behalten?
Ich möchte eine Lösung, die für meine anderen Projekte verwendet werden könnte.

Imports System 
    Imports System.Text 
    Imports System.Xml 
    Imports System.IO 

    Public Class Form1 

     Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 

      dgv.Columns.Add("col0", "col0") 
      dgv.Columns(0).ValueType = Type.GetType("Integer") 
      dgv.Columns.Add("col1", "col1") 
      dgv.Columns.Add("col2", "col2") 
      dgv.Columns(2).ValueType = Type.GetType("Double") 
      dgv.Columns(2).DefaultCellStyle.Format = "N2" 

      dgv.Rows.Add({CInt("1"), "John", CDbl("0,11")}) 
      dgv.Rows.Add({CInt("2"), "Mary", CDbl("2,8")}) 
      dgv.Rows.Add({CInt("3"), "Mike", CDbl("10,125")}) 
      dgv.Rows.Add({CInt("4"), "Suzy", CDbl("2")}) 
     End Sub 

     Private Sub dgv_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles dgv.Leave 

      If dgv.Rows.Count - 1 > 0 Then 
       Dim dsa As DataSet = New DataSet() 
       dsa.DataSetName = "xdgv" 
       Dim dxs As DataTable = GetDataTableFromDGV(dgv) 
       dsa.Tables.Add(dxs) 
       ''save xml from dgv content to textbox 
       TextBox1.Text = GenerateXML(dsa) 
      End If 
     End Sub 

     Private Function GenerateXML(ByVal xds As DataSet) As String 

      Dim obj As New StringWriterUtf8() 
      Dim xmlstring As String 
      xds.WriteXml(obj, XmlWriteMode.IgnoreSchema) 
      xmlstring = obj.ToString() 

      Return xmlstring 
     End Function 

     Private Function GetDataTableFromDGV(ByVal dgv As DataGridView) As DataTable 

      Dim dt = New DataTable() 

      Dim t As Integer = 0 
      For Each column As DataGridViewColumn In dgv.Columns 
       If column.Visible Then 
        dt.Columns.Add(dgv.Columns(t).Name) 
        t += 1 
       End If 
      Next 

      Dim cellValues As Object() = New Object(dgv.Columns.Count - 1) {} 
      For Each row As DataGridViewRow In dgv.Rows 
       If Not row.IsNewRow Then 
        For i As Integer = 0 To row.Cells.Count - 1 
         cellValues(i) = If(row.Cells(i).Value Is Nothing, String.Empty, row.Cells(i).Value) 
        Next 
        dt.Rows.Add(cellValues) 
       End If 
      Next 

      Return dt 
     End Function 

     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 

      ''load xml from textbox back to dgv 
      dgv.Rows.Clear() 

      If Not String.IsNullOrEmpty(TextBox1.Text) Then 
       Try 
        Dim Stream As StringReader = New StringReader(TextBox1.Text) 
        Dim xreader As XmlTextReader = New XmlTextReader(Stream) 
        Dim ds As DataSet = New DataSet 
        ds.ReadXml(xreader) 
        For Each table As DataTable In ds.Tables 
         For Each row As DataRow In table.Rows 
          dgv.Rows.Add(row.ItemArray()) 
         Next row 
        Next table 
        ds = Nothing 
       Catch ex As Exception 
        MessageBox.Show("xmlFoo: " + ex.Message) 
       End Try 
      End If 
     End Sub 
    End Class 

    Public Class StringWriterUtf8 
     Inherits System.IO.StringWriter 
     Public Overrides ReadOnly Property Encoding() As Encoding 
      Get 
       Return Encoding.UTF8 
      End Get 
     End Property 
    End Class 

Für diesen Code erfolgreich ausgeführt würden Sie auf das neue Projekt mit Form1 müssen die Datagridview enthält = „dgv“, Textfeld = „TextBox1“ und Button = „Button1“.

Antwort

1

Hier ist eine neue Lösung, die einige Nacharbeit in Ihrem Namen erfordert. Anstatt die Datagrid-Ansicht aufzufüllen, befüllen Sie eine Datentabelle und verwenden Sie diese, um die Bindung und Serialisierung durchzuführen.

Hier ist ein Beispielcode, der die erstellte Tabelle zeigt, die an die Gridview gebunden, serialisiert und deserialisiert ist, wobei die Typen intakt sind.

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
    Dim dt As New DataTable("Src") 
    dt.Columns.Add("col0", GetType(Integer)) 
    dt.Columns.Add("col1", GetType(String)) 
    dt.Columns.Add("col2", GetType(Double)) 

    dt.Rows.Add({CInt("1"), "John", CDbl("0,11")}) 
    dt.Rows.Add({CInt("2"), "Mary", CDbl("2,8")}) 
    dt.Rows.Add({CInt("3"), "Mike", CDbl("10,125")}) 
    dt.Rows.Add({CInt("4"), "Suzy", CDbl("2")}) 

    dgv.DataSource = dt 
    dgv.Columns(2).DefaultCellStyle.Format = "N2" 

    Dim file = "c:\temp\test.xml" 
    dt.WriteXml(file, XmlWriteMode.WriteSchema) 

    Dim dt2 = New DataTable 
    dt2.ReadXml(file) 

    dgv.DataSource = dt2 
End Sub 

Ihre modifizierte GenerateXml Funktion:

Private Function GenerateXML(ByVal dt As DataTable) As String 
    Dim obj As New StringWriterUtf8() 
    Dim xmlstring As String 
    dt.WriteXml(obj, XmlWriteMode.WriteSchema) 
    xmlstring = obj.ToString() 
    TextBox1.Text = xmlstring 
    Return xmlstring 
End Function 

Unabhängige Schemen

Dim file = "c:\temp\test.xml" 
    Dim schema = "c:\temp\test.xsd" 
    dt.WriteXml(file, XmlWriteMode.IgnoreSchema) 
    dt.WriteXmlSchema(schema) 

    Dim dt2 = New DataTable 
    dt2.ReadXmlSchema(schema) 
    dt2.ReadXml(file) 
+0

Hm, nicht genau, wie ich will, aber funktioniere. Ist hier eine Möglichkeit, String (Textbox) anstelle von Datei zu verwenden? – user1697111

+0

Ich habe gerade Ihre GenerateXml-Funktion geändert, um stattdessen die Datentabelle zu verwenden. Dieser Ansatz sollte die Menge an Code, die Sie haben, drastisch reduzieren. – FloatingKiwi

+0

Ja, das funktioniert gut. Ich möchte nur String statt Datei verwenden. Dieser Teil mit neuer GenerateXML geht gut. Ich bin auch erfolgreich löschen Sie die DataTable und neu laden Sie es aus Textfeld, dann erneut an dgv erneut. Das bedeutet, dass ich mit einer Datentabelle statt zwei arbeite ... Viel bessere Lösung als meine Initiale. Vielen Dank. Aber ich frage mich, warum ich nicht richtig Typ od dgv Spalte lesen kann sowieso ... Wir würden das nächste Mal lösen :) – user1697111

Verwandte Themen