0

叹息...我有一个具有事件属性的类。当属性值发生变化时触发该事件。类的实例是表单信息的支持者。我需要保存表格中的信息以供以后调用。

这里的想法是将属性作为数据源绑定到表单上的文本框和 datagridview。那是当类的值发生变化时更新文本框或数据网格视图的事件的驱动程序。

所以......当我使用以下代码保存静态变量(测试)的文件时,它可以正常工作:

Dim test As String = "Hello"
    ' Persist to file
Dim save As New SaveFileDialog
If save.ShowDialog = Windows.Forms.DialogResult.OK Then
    Dim stream As FileStream = File.Create(save.FileName)
    Dim formatter As New BinaryFormatter()
    formatter.Serialize(stream, test)
    stream.Close()
End If

如果我使用支持数据的类的实例尝试它,它会抛出错误,因为该类有事件:

Dim test As new ClassWithEvents()
    ' Persist to file
Dim save As New SaveFileDialog
If save.ShowDialog = Windows.Forms.DialogResult.OK Then
    Dim stream As FileStream = File.Create(save.FileName)
    Dim formatter As New BinaryFormatter()
    formatter.Serialize(stream, test)
    stream.Close()
End If

错误:

在程序集“System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”中键入“System.Windows.Forms.Form”未标记为可序列化。

我真正想做的就是将控件的值保留在表单上以供以后调用。

有任何想法吗?

4

2 回答 2

1

这里可能的失败模式是您的类有一个已订阅的事件。事件处理程序的目标是属于 Form 类的方法。是的,那行不通,Form 类不可序列化。您也不想序列化事件,它不太可能正确反序列化。

<NonSerialized>您可以通过在成员上应用属性来抑制类成员的序列化。不幸的是,这在 VB.NET 中很难做到,它不适用于使用 Event 关键字声明的成员。VB.NET 事件相当特殊。解决方法是改用自定义事件,它使用可以防止被序列化的私有支持字段。看起来像这样:

<Serializable()> _
Class ClassWithEvents
    <NonSerialized()> _
    Private Events As New System.ComponentModel.EventHandlerList

    Public Custom Event Foo As EventHandler
        AddHandler(ByVal value As EventHandler)
            Events.AddHandler("foo", value)
        End AddHandler

        RemoveHandler(ByVal value As EventHandler)
            Events.RemoveHandler("foo", value)
        End RemoveHandler

        RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
            CType(Events("foo"), EventHandler).Invoke(sender, e)
        End RaiseEvent
    End Event

    '' etc..
End Class

你必须为课堂上的每个事件都这样做。您可以重复使用 Events 变量,只需将“foo”更改为“bar”。当然不是很有趣。请考虑使用仅具有要序列化的属性的专用类作为替代方案。

于 2013-10-02T22:05:13.980 回答
0

既然您说过“我真正想做的就是将控件的值保留在表单上以供以后调用”,因此一些可能的方法是:

  1. 递归遍历窗体上的所有控件(和子控件),并将相关属性存储在可序列化的数据结构中。

  2. 将您的控件绑定到内存数据库,并从中序列化您的数据。

于 2013-10-02T23:58:31.227 回答