简体   繁体   English

c#我如何以编程方式创建表单的副本?

[英]c# how do i programmatically create a replica of my form?

i am using winforms with visual studio 2008. 我正在使用winforms与visual studio 2008。

i would to create an EXACT replica of my form with controls and all events, and all the same code as i have. 我想用控件和所有事件创建一个我的表单的EXACT副本,以及我所拥有的所有相同代码。

is this possible to do at runtime? 这可以在运行时做吗? how would i do it? 我该怎么办?

shouldnt there be some kind of class solution like: 不应该有某种类解决方案,如:

Form form2 = new Form();
form2 = form1 ???

Just create another instance of the same class. 只需创建同一个类的另一个实例。 Use the actual name of the class instead of the base class Form . 使用类的实际名称而不是基类Form

Form form2 = new Form1();
form2.Show();

Shooting from the hip, serialize the form and deserialize it into the second variable. 从臀部拍摄,序列化表单并将其反序列化为第二个变量。 : ) I'll try to look into this and come up with more of an answer. :)我会尝试研究这个并提出更多答案。

Some things to watch out for... do you want a shallow or deep copy? 有些事情要注意......你想要一个浅或深的副本吗? IE, if the form has a reference to an object, do you want to copy the reference (so both forms are pointing to the same object), or make a copy of that object, also? IE,如果表单有对象的引用,你想复制引用(所以两个表单都指向同一个对象),还是复制该对象? You have to be careful... there's no guarantee with objects that contain references to other objects which order they will be deserialized 你必须要小心......对于包含对其他对象的引用的对象,不能保证它们将被反序列化

You don't need to, but it's good practice to inherit from ICloneable, which has only one method, Clone() . 您不需要,但从IClo​​neable继承是一种好习惯,ICloneable只有一个方法Clone() Override this method with code similar to the following: 使用类似于以下内容的代码覆盖此方法:

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);

}

To use: 使用:

MyForm form2 = form1.Clone() as MyForm;
if (form2 != null) {
    // yahoo!
}

* Edit * *编辑*
There's actually an excellent example here on SO that creates a generic object copier. 实际上在SO上有一个很好的例子,可以创建一个通用的对象复制器。 Very nice! 非常好!
Deep cloning objects 深度克隆对象


* Edit * *编辑*
The problem with serializing the form is that not all the values can really be serialized... they make no sense, eg the handles on the individual controls. 序列化表单的问题在于并非所有值都可以真正序列化......它们没有任何意义,例如各个控件上的句柄。

To make the form serializable, you will need to implement the ISerializable interface, and implement the proper constructor and GetObjectData() method. 要使表单可序列化,您需要实现ISerializable接口,并实现正确的构造函数和GetObjectData()方法。 In GetObjectData, you will need to enumerate your controls, and store the properties (eg Text or Value) that you want to copy. 在GetObjectData中,您需要枚举控件,并存储要复制的属性(例如Text或Value)。 The constructor reads them back out. 构造函数将它们读回来。 It looks like this: 它看起来像这样:

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);
        }

    }

}

The idea is, enumerate the form, put every value into SerializationInfo stream, and pull it back out when you create a new object. 我们的想法是,枚举表单,将每个值放入SerializationInfo流中,并在创建新对象时将其拉出。 This will allow my original code for Cloning to work. 这将允许我的克隆原始代码工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM