2016-08-15 66 views
0

我想保存和加載到一個DataGridView的XML字符串。
下面的代碼我可以做到這一點,但列的數據類型丟失,然後整個網格只填充字符串。在這種情況下,格式化和排序不再適用。DataGridView到保留的數據類型的XML

在這裏,我可以做些什麼來保持顯示過程中的原始數據類型?
我想要我的其他項目可用的解決方案。

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 

對於成功地運行該代碼,你需要與Form1中就可以了新的項目,它包含的DataGridView =「DGV」,文本框=「TextBox1的」和按鈕=「Button1的」。

回答

1

這是一個新的解決方案,需要代表您進行一些修改。而不是填充datagridview,填充數據表並使用它來執行綁定和序列化。

下面是一些示例代碼,它顯示了正在創建的表格,綁定到gridview,序列化和反序列化,完整的類型。

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 

你修改GenerateXml功能:

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 

獨立架構

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

嗯,我不完全怎麼想,但工作。這裏有任何方式使用字符串(文本框),而不是文件? – user1697111

+0

我剛剛修改了您的GenerateXml函數以改爲使用datatable。這種方法應該大大減少你得到的代碼量。 – FloatingKiwi

+0

是的,這很好。我只想使用字符串而不是文件。這部分與新的GenerateXML很好。我也成功地清除了DataTable並從Textbox重新加載它,然後再次重新綁定到dgv。這意味着我工作一個數據表而不是兩個...更好的解決方案,然後是我的初始。非常感謝你。但我想知道爲什麼我無論如何都無法正確讀取od dgv列......我們將在下次解決這個問題:) – user1697111