【问题标题】:Why are System.Windows.Forms.Control not marked as serializable?为什么 System.Windows.Forms.Control 未标记为可序列化?
【发布时间】:2012-02-25 23:43:18
【问题描述】:

我无法深度复制 UserControl,因为它们没有被标记为可序列化。

这种设计背后的原因是什么?

【问题讨论】:

    标签: c# .net visual-studio oop c#-4.0


    【解决方案1】:

    序列化控件不是问题,反序列化它很难做到正确。期望这将生成控件的 exact 克隆。这几乎不可能准确地做到,有大量的运行时状态与控件相关联。不仅在 Control 类对象本身,在窗口的内部状态中,也表明 Windows 不允许你直接访问。

    但最终的问题是它具有与流程实例相关联的状态。重要的内部属性(如 Windows 窗口类名称和秘密属性访问器密钥)因程序的一次运行而异。因此,在之前的程序运行或其他程序的序列化中重新创建控件是不可能的。

    也就是说,Winforms 设计器实际上支持控件序列化。不是字节,它生成代码。在运行时重新创建控件的代码,看起来与设计时相同。减去一大堆细节,如尺寸和颜色,它们在另一台机器上通常会有所不同。设计器的一大优势是它只需要序列化控件的 initial 状态,即它在构造函数时的状态。在此之后的任何时候都这样做,在 Windows 创建控件的窗口并向其发送一堆消息之后,这是一个更难破解的难题。这是一个错误工厂。因此不受支持。

    【讨论】:

      【解决方案2】:

      用户控件是一种视觉元素,因此您为什么要序列化它们?您永远不会通过 WCF 服务发送它们,或将它们流式传输到数据存储库。如果您需要传输或存储用户控件,那么您将存储它们的关键属性并在必要时重新创建它们。

      不要使用序列化来创建克隆,而是使用更传统的方法,例如手动复制已知类型的特定属性,或使用反射。

      【讨论】:

      • 这种方法是否可扩展,即如果用户控件随着时间的推移变得更加复杂,我们可能不得不一遍又一遍地修改逻辑?
      • 视觉元素没有理由是可序列化的 - 它们像许多其他对象一样包含状态。
      • @adelphus,另一方面,它们包含一些非常特殊的难以序列化的状态(参见 Hans 的回答)。
      【解决方案3】:

      您可以序列化控件,但不能通过标准序列化程序。 如果您想序列化表单上的一个或多个控件以保存表单设计和/或其他控件属性,您可以使用 Visual Studio 使用的相同序列化(通过 CodeDomSerializer),但您需要实现几个类(我认为至少IDesignerSerializationManager)。 您可以在此处查看示例

      http://support.microsoft.com/default.aspx?scid=kb;en-us;813808

      序列化在 Class SampleDesignerLoader 方法 Flush 中。

      在同样的方法中,还有一个 XML 流中的序列化,它不使用 Visual Studio 使用的类。

      在同一个类中,还有来自 XML 的反序列化。

      【讨论】:

        猜你喜欢
        • 2017-02-21
        • 2015-11-10
        • 2016-01-18
        • 2011-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-20
        相关资源
        最近更新 更多