【发布时间】:2012-02-25 23:43:18
【问题描述】:
我无法深度复制 UserControl,因为它们没有被标记为可序列化。
这种设计背后的原因是什么?
【问题讨论】:
标签: c# .net visual-studio oop c#-4.0
我无法深度复制 UserControl,因为它们没有被标记为可序列化。
这种设计背后的原因是什么?
【问题讨论】:
标签: c# .net visual-studio oop c#-4.0
序列化控件不是问题,反序列化它很难做到正确。期望这将生成控件的 exact 克隆。这几乎不可能准确地做到,有大量的运行时状态与控件相关联。不仅在 Control 类对象本身,在窗口的内部状态中,也表明 Windows 不允许你直接访问。
但最终的问题是它具有与流程实例相关联的状态。重要的内部属性(如 Windows 窗口类名称和秘密属性访问器密钥)因程序的一次运行而异。因此,在之前的程序运行或其他程序的序列化中重新创建控件是不可能的。
也就是说,Winforms 设计器实际上支持控件序列化。不是字节,它生成代码。在运行时重新创建控件的代码,看起来与设计时相同。减去一大堆细节,如尺寸和颜色,它们在另一台机器上通常会有所不同。设计器的一大优势是它只需要序列化控件的 initial 状态,即它在构造函数时的状态。在此之后的任何时候都这样做,在 Windows 创建控件的窗口并向其发送一堆消息之后,这是一个更难破解的难题。这是一个错误工厂。因此不受支持。
【讨论】:
用户控件是一种视觉元素,因此您为什么要序列化它们?您永远不会通过 WCF 服务发送它们,或将它们流式传输到数据存储库。如果您需要传输或存储用户控件,那么您将存储它们的关键属性并在必要时重新创建它们。
不要使用序列化来创建克隆,而是使用更传统的方法,例如手动复制已知类型的特定属性,或使用反射。
【讨论】:
您可以序列化控件,但不能通过标准序列化程序。 如果您想序列化表单上的一个或多个控件以保存表单设计和/或其他控件属性,您可以使用 Visual Studio 使用的相同序列化(通过 CodeDomSerializer),但您需要实现几个类(我认为至少IDesignerSerializationManager)。 您可以在此处查看示例
http://support.microsoft.com/default.aspx?scid=kb;en-us;813808
序列化在 Class SampleDesignerLoader 方法 Flush 中。
在同样的方法中,还有一个 XML 流中的序列化,它不使用 Visual Studio 使用的类。
在同一个类中,还有来自 XML 的反序列化。
【讨论】: