c#如何以编程方式创建表单的副本?
我正在visual studio 2008中使用winforms 我想创建一个与我的表单完全相同的副本,包括控件和所有事件,以及所有与我相同的代码 这可以在运行时执行吗?我该怎么做 难道不应该有一些类解决方案,如:c#如何以编程方式创建表单的副本?,c#,.net,winforms,.net-3.5,C#,.net,Winforms,.net 3.5,我正在visual studio 2008中使用winforms 我想创建一个与我的表单完全相同的副本,包括控件和所有事件,以及所有与我相同的代码 这可以在运行时执行吗?我该怎么做 难道不应该有一些类解决方案,如: Form form2 = new Form(); form2 = form1 ??? 只需创建同一类的另一个实例。使用类的实际名称,而不是基类表单 Form form2 = new Form1(); form2.Show(); 从头开始,序列化表单并将其反序列化到第二个变量中。:
Form form2 = new Form();
form2 = form1 ???
只需创建同一类的另一个实例。使用类的实际名称,而不是基类
表单
Form form2 = new Form1();
form2.Show();
从头开始,序列化表单并将其反序列化到第二个变量中。:)我会努力研究这个问题,并提出更多的答案 一些需要注意的事情。。。你要浅拷贝还是深拷贝?也就是说,如果表单对某个对象有引用,您是要复制引用(因此两个表单都指向同一个对象),还是也要复制该对象?你必须小心。。。对于包含对其他对象的引用的对象,不能保证它们的反序列化顺序 您不需要这样做,但是从ICloneable继承是一种好的做法,它只有一个方法,
Clone()
。使用类似以下代码重写此方法:
public object Clone() {
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, this);
stream.Seek(0, SeekOrigin.Begin);
return (MyForm) formatter.Deserialize(stream);
}
使用:
MyForm form2 = form1.Clone() as MyForm;
if (form2 != null) {
// yahoo!
}
*编辑*这里有一个很好的例子,可以创建一个通用的对象复制器。非常好
*编辑*
序列化表单的问题是并非所有的值都可以真正序列化。。。它们毫无意义,例如单个控件上的手柄 要使表单可序列化,需要实现ISerializable接口,并实现适当的构造函数和GetObjectData()方法。在GetObjectData中,需要枚举控件,并存储要复制的属性(例如文本或值)。构造函数将它们读回。看起来是这样的:
public partial class MyForm : Form, ISerializable {
public MyForm() {}
public MyForm(SerializationInfo info, StreamingContext context) : base() {
foreach (Control control in Controls) {
control.Text = info.GetString(control.Name);
}
}
public void GetObjectData(SerializationInfo info, StreamingContext context) {
foreach (Control control in Controls) {
info.AddValue(control.Name, control.Text);
}
}
}
其思想是,枚举表单,将每个值放入SerializationInfo流,并在创建新对象时将其取出。这将允许我的原始克隆代码工作。@guffa我认为如何在该表单上运行方法?例如,如果我想在新表单2上触发点击事件,我将如何做?新表单2本身将处理自己的点击事件。如果您想从form2 itseld外部启动新form2上的方法,请将该方法公开(或内部等),然后通过调用form2.YourMethodName()来启动它。@jay您能给我举个例子吗please@jay我如何在form2上填写文本框?如果你想在form2之外填写,您可以将文本框的Modifiers属性更改为public,然后通过调用form2.YourTextBox.text=“我的文本”来设置文本框文本@james谢谢你,但我需要从基本表单运行方法,我该怎么做呢?实际上,我必须收回我的答案并重新思考。。。您不能将表单标记为可序列化,因此我的方法不起作用:(好的,添加了关于如何序列化表单的信息。我不确定你所说的“需要从基表单运行方法”是什么意思?为什么要经历这些麻烦?因为如果你想要一个表单的副本,这意味着你想要一个所有控件、它们的值等的副本,以及你给表单的任何成员级变量的副本。唯一的方法是复制其中的一个是从Clone()或Copy()方法的表单中枚举它们。从类中序列化意味着您不必将每个控件作为公共属性公开,如果您想从外部创建副本,则必须这样做。