具有保留数据类型的DataGridView到XML

时间:2016-08-15 09:23:35

标签: xml vb.net datagridview

我正在尝试从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

对于成功运行此代码,您需要包含DataGridView =“dgv”,Text box =“TextBox1”和Button =“Button1”的Form1新项目。

1 个答案:

答案 0 :(得分: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)