是的,我知道与此主题相关的无数帖子;但是,我一直无法找到答案。
我正在为RPG制作角色编辑器,我需要一个组合框来从Debug文件夹中的文件加载东西。我得到了节约;装载是我得到的。
我的代表不够高,无法发布图片,所以我会尝试彻底解释。
有两个组合框和三个按钮。
第一个组合框是用户输入所需字符的名称,然后按"添加"按钮保存以供日后使用。然后,一旦用户输入了所有字符的名称,他们就按下" Save"按钮将它们保存在看起来像这样的XML文件中,例如:
<?xml version="1.0" standalone="yes"?>
<DocumentElement>
<character>
<name0>Banana</name0>
</character>
<character>
<name1>Fruit</name1>
</character>
<character>
<name2>Grapes</name2>
</character>
<character>
<name3>Oranges</name3>
</character>
<character>
<name4>Taco</name4>
</character>
<character>
<count>5</count>
</character>
</DocumentElement>
注意最后总会有一个&#34;字符&#34;命名为 count 。这是输入的名称数量。根据您碰巧的解决方案,这可能会或可能不会继续。我总是在寻找一种更有效的方法,所以我会发布用于保存名称的代码。
Private Sub saveFile(ByVal filename As String)
count = NameBox.Items.Count
REM create xml schema
Dim table As New DataTable("character")
Try
For x = 0 To count
If x <= count - 1 Then
table.Columns.Add(New DataColumn("name" & x.ToString(),
System.Type.GetType("System.String")))
REM copy character data into datatable
Dim row As DataRow = table.NewRow()
row("name" & x.ToString()) = NameBox.Items.Item(x)
table.Rows.Add(row)
End If
If x = count Then
table.Columns.Add(New DataColumn("count",
System.Type.GetType("System.String")))
Dim row2 As DataRow = table.NewRow()
row2("count") = count.ToString()
table.Rows.Add(row2)
End If
Next
table.WriteXml(filename)
table.Dispose()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub SaveButton_Click(sender As System.Object, e As
System.EventArgs) Handles SaveButton.Click
Save1.DefaultExt = ".char"
Save1.Filter = "Character Data Files|*.char"
Save1.Title = "Save Character File"
Save1.InitialDirectory = Environment.CurrentDirectory
Dim result As DialogResult
result = Save1.ShowDialog(Me)
If result <> Windows.Forms.DialogResult.OK Then Return
g_filename = Save1.FileName
saveFile(g_filename)
End Sub
注意:
Save1是一个SaveFileDialog。 NameBox是第一个组合框。 SupportBox是第二个。这些是我的globals-g_filename为String,计为Integer
现在,让我们进入这个文件的实际加载。这是我尝试过的,当然我得到了臭名昭着的错误&#34;对象引用未设置为对象的实例&#34;这是一种精心设计的说法&#34;你完成了索引或其他任何事情。&#34;
我已经根据自己的知识在线尝试了各种各样的事情。我没有公布我的所有尝试,而是将其留在此处。
基本上,我想要的是在按下“加载”按钮后将文件加载到第二个组合框(SupportBox)。
count ,正如您所猜测的那样,似乎需要包含在文件中,因此循环将知道在加载文件中的所有内容时要走多远,以防止索引错误;它也是需要的,以便程序可以在没有最初加载名称的情况下工作,从而增加了计数。 “加载”按钮需要单独运行。
如何加载此文件?
提前感谢您的帮助。
编辑:
根据请求,我会在加载此文件的一次尝试上发布一些代码。
Private Sub loadName(ByVal filename As String)
Try
Dim doc As New XmlDocument()
doc.Load(filename)
Dim list As XmlNodeList = doc.GetElementsByTagName("character")
Dim element As XmlElement = list(0)
For x = 1 To count
SupportBox.Items.Add(getElement("Name" & x.ToString(), element))
Next
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Function getElement(ByVal field As String, ByRef element As
XmlElement) As String
Dim value As String = ""
Try
value = element.GetElementsByTagName(field)(0).InnerText
Catch ex As Exception
REM ignore error, just return empty
MessageBox.Show(ex.Message)
End Try
Return value
End Function
答案 0 :(得分:1)
您的对象模型非常简单,您无需使用DataTable进行XML反序列化/序列化。我总是试图避免使用DataTables,因为我发现以下方法更容易。
以下是反序列化和序列化对象的常用方法:
Private Function Deserialize(Of T)(ByVal strXML As String) As T
Dim objXMLSerializer As New System.Xml.Serialization.XmlSerializer(GetType(T))
Dim objStringReader As New System.IO.StringReader(strXML)
Return objXMLSerializer.Deserialize(objStringReader)
End Function
Private Function Serialize(ByRef TargetObject As Object) As String
Dim objXmlSerializer As New System.Xml.Serialization.XmlSerializer(TargetObject.GetType())
Dim objStringWriter As New System.IO.StringWriter()
objXmlSerializer.Serialize(objStringWriter, TargetObject)
Return objStringWriter.ToString()
End Function
接下来,创建一个用于编写XML文件的方法。您会注意到它使用上面的Serialize()函数。这样的事情应该有效:
Private Sub Write()
Dim lstCharacters As New List(Of character)
For x = 0 To (count - 1)
Dim objCharacter As New character
objCharacter.name = NameBox.Items.Item(x)
lstCharacters.Add(objCharacter)
Next
IO.File.WriteAllText("C:\Some\Path.xml", Serialize(lstCharacters))
End Sub
接下来,创建一个加载XML文件的方法。这个使用上面的Deserialize()函数。看看我如何轻松地获得此方法中的计数。
Private Sub Read()
Dim lstCharacters As List(Of character) = Deserialize(Of List(Of character))(IO.File.ReadAllText("C:\Test\TestSO1.xml"))
Dim intCharacterCount As Integer = lstCharacters.Count
For Each objCharacter As character In lstCharacters
'SupportBox.Items.Add(getElement("Name" & x.ToString(), element))
Next
End Sub
使用此解决方案,您不再需要使用DataTable或担心Count。生成的XML将与原始解决方案不同,但由于索引不再附加在name元素上,因此更加清晰。