【问题标题】:DataGridView to XML with preserved datatypes保留数据类型的 DataGridView 到 XML
【发布时间】:2016-08-15 09:23:35
【问题描述】:

我正在尝试在 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"、Text box="TextBox1" 和 Button="Button1"。

【问题讨论】:

    标签: xml vb.net datagridview


    【解决方案1】:

    这是一个新的解决方案,需要代表您进行一些修改。不要填充数据网格视图,而是填充数据表并使用它来进行绑定和序列化。

    这里是一些示例代码,显示了正在创建的表、绑定到 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)
    

    【讨论】:

    • 嗯,不完全是我想要的,但可以工作。这里有什么方法可以使用字符串(文本框)而不是文件吗?
    • 我刚刚修改了您的 GenerateXml 函数以改用数据表。这种方法应该会大大减少您拥有的代码量。
    • 是的,效果很好。我只想使用字符串而不是文件。这部分带有新的 GenerateXML 很好。我也成功清除了 DataTable 并从 Textbox 重新加载,然后再次重新绑定到 dgv。这意味着我使用一个数据表而不是两个数据表......比我最初的解决方案要好得多。非常感谢你。但是我想知道为什么我无论如何都无法读取正确的类型 od dgv 列......我们下次会解决这个问题:)
    • 最后,还有一个理论问题。我将该 XML 存储在数据库中。会有很多这些 xml 字符串。是否可以在字符串中也有模式以供即时使用。我的意思是不要将它与每个 xml 字符串一起存储。你怎么看?
    • 是的,有可能。您可以使用 writexmlschema 方法,但我不在我的机器旁,所以没有详细信息。然而,问题是你应该这样做吗?为什么不将数据保存为记录并根据需要进行查询。根本不需要 XML 序列化。
    猜你喜欢
    • 1970-01-01
    • 2012-03-19
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-28
    • 2015-08-10
    • 1970-01-01
    相关资源
    最近更新 更多