0

我设法序列化面板上的每个对象,并将其放入具有一些属性的 .dat 文件中(我将在以后完成所有可能的属性)。该文件如下所示:

<DocumentElement>
 <Controls>
   <Name>Label2</Name>
   <Text>hyvgiyb</Text>
   <Width>74</Width>
   <Height>21</Height>
   <Top>173</Top>
   <Left>269</Left>
 </Controls>
 <Controls>
   <Name>Label1</Name>
   <Text>Picture</Text>
   <Width>74</Width>
   <Height>21</Height>
   <Top>114</Top>
   <Left>240</Left>
 </Controls>
</DocumentElement

那只是两个只有几个属性的控件。我现在想将 Xml 转换为控件的属性,这样我就可以添加一个控件并简单地执行以下操作:

'code to add control
'control properties
 .Name = DataFromXml
 .Text = DataFromXml
 '...etc

不要担心添加控件的代码,因为我已经有了它;我只需要获取每个控件的各个属性(每个控件的属性都保存在 . 之间,这需要以某种方式分开)。

澄清一下,我正在读取和写入 .dat 文件并在 Visual Studio 2012 中使用 VB.NET。非常感谢任何帮助,谢谢:)

4

2 回答 2

0

用反射分配值怎么样?有点儿:

var control = FindByName(...);

foreach (var node in xmlNode.Children) {
    typeof(control).GetProperty(node.Name).SetValue(control, node.InnerText)
}
于 2013-10-02T17:48:00.390 回答
0

您可能不想实际读取 XML 文件。无论控件在 (list(of?), collection?) 中的哪个位置被序列化,XML 都可以反序列化为相同的东西,这可能会更容易。例如,如果您序列化了包含这些属性的类的集合,您可以将其取回。

否则,可能会将 XML 读入数据表(还有其他方法):

Dim ds As New DataSet()
Dim dt as New DataTable
' Create new FileStream with which to read the file
Dim fsReadXml As New System.IO.FileStream _
    (myXMLfile, System.IO.FileMode.Open)
Try
    ds.ReadXml(fsReadXml)

Catch ex As Exception
    MessageBox.Show(ex.ToString())
Finally
    fsReadXml.Close()
End Try
dt = ds.Tables(0)

然后循环遍历表以将属性值获取到您添加到父控件数组中的新控件。每个dt.Rows将包含 1 个控件的数据,列将包含每个属性。由于您创建了文件,因此您知道列名是什么,并且可以按名称引用它们:

For each dr as Datarow  In ds.Tables(0).Rows
    Dim lbl as New Label

    With lbl
     .Top = dr.Item("Top")
     ' etc etc etc
    End with

   ' add to parent
    pnlThing.Controls.Add(lbl)

 Next

使用 XML 源时会遇到的问题是,如果其中有不同类型的控件,您还需要保存 ctl.Type,然后从名称中解析出它是什么类型的控件。

编辑:二进制序列化器更容易:

    For Each ctl As Control In pnl1.Controls
        Dim c As New Class1
        c.sz = ctl.Size
        c.pt = ctl.Location
        c.name = ctl.Name

        L.Add(c)
    Next

    ' Persist to file
    Dim stream As FileStream = File.Create("C:\Temp\bin.dat")
    Dim formatter As New BinaryFormatter()
    formatter.Serialize(stream, L)         ' NOTE serialize the LIST of Class1
    stream.Close()

当您反序列化时,您将拥有一个新的 List(of Class1),其中包含您可以在“组”中引用的所有道具或您已经知道的东西集,例如 SIZE 而不是 Width 和 Height。它显然不会处理Controls数组,因此需要收集你需要的任何东西。

于 2013-10-02T17:48:49.410 回答