C# 如何克隆具有不可序列化属性的Windows窗体控件?

C# 如何克隆具有不可序列化属性的Windows窗体控件?,c#,winforms,serialization,clone,deep-copy,C#,Winforms,Serialization,Clone,Deep Copy,如何克隆或序列化Windows窗体控件? 当我尝试使用此代码“CloneControl(Control ct1)”克隆windows窗体控件时,它允许我使用某些可序列化属性(而不是所有属性)复制控件 public Form1() { InitializeComponent(); Columns = new DataGridViewTextBoxColumn[2]; for (int i = 0; i < 2; i++) {

如何克隆或序列化Windows窗体控件?
当我尝试使用此代码“CloneControl(Control ct1)”克隆windows窗体控件时,它允许我使用某些可序列化属性(而不是所有属性)复制控件

public Form1()
{
    InitializeComponent();
        Columns = new DataGridViewTextBoxColumn[2];
        for (int i = 0; i < 2; i++)
        {
            Columns[i] = new System.Windows.Forms.DataGridViewTextBoxColumn();
            // 
            // Columns[i]
            // 
            Columns[i].HeaderText = "j" + (i + 1);
            Columns[i].Name = "Column" + (i + 1);
            Columns[i].Width = 50;
        }
        dataGridView1 = new System.Windows.Forms.DataGridView();
        dataGridView1.Name = "dataGridView1";
        dataGridView1.Location = new System.Drawing.Point(100, 100);
        dataGridView1.RowHeadersWidth = 50;
        dataGridView1.RowTemplate.Height = 25;
        dataGridView1.Size = new System.Drawing.Size(55 + 50 * 2, 25 + dataGridView1.RowTemplate.Height * 2);
        dataGridView1.Anchor = System.Windows.Forms.AnchorStyles.None;
        dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        dataGridView1.Columns.AddRange(Columns);
        dataGridView1.TabIndex = 3;
        dataGridView1.AllowUserToAddRows = false;
        dataGridView1.Rows.Add();
        dataGridView1.Rows.Add();
        dataGridView1.Rows[0].HeaderCell.Value = "i" + 1;
        dataGridView1.Rows[1].HeaderCell.Value = "i" + 2;
        dataGridView1.Rows[0].Cells[0].Value = "value1";
        Controls.Add(dataGridView1);

        Control cloned1 = CloneControl(dataGridView1); 
        cloned1.SetBounds(cloned1.Location.X, cloned1.Location.Y + 300, cloned1.Width, ct1.Height);
        Controls.Add(cloned1);
        cloned1.Show();
}    

public Control CloneControl(Control ct1)
{
    Hashtable PropertyList = new Hashtable();
    PropertyDescriptorCollection Properties = TypeDescriptor.GetProperties(ct1);
    Assembly controlAsm = Assembly.LoadWithPartialName(ct1.GetType().Namespace);
    Type controlType = controlAsm.GetType(ct1.GetType().Namespace + "." + ct1.GetType().Name);
    Control cloned1 = (Control)Activator.CreateInstance(controlType);
    foreach (PropertyDescriptor pr1 in Properties)
    {
        if (pr1.PropertyType.IsSerializable)
        {
            PropertyList.Add(pr1.Name, pr1.GetValue(ct1));
        }
        if (PropertyList.Contains(pr1.Name))
        {
            try
            {
                 Object obj = PropertyList[pr1.Name];
                 pr1.SetValue(cloned1, obj);
            }
            catch (Exception ex)
            {

            }
        }
    }
    return ct2;
}
public Form1()
{
初始化组件();
Columns=新的DataGridViewTextBoxColumn[2];
对于(int i=0;i<2;i++)
{
Columns[i]=new System.Windows.Forms.DataGridViewTextBoxColumn();
// 
//第[i]栏
// 
列[i].HeaderText=“j”+(i+1);
列[i].Name=“列”+(i+1);
列[i]。宽度=50;
}
dataGridView1=新建System.Windows.Forms.DataGridView();
dataGridView1.Name=“dataGridView1”;
dataGridView1.Location=新系统.Drawing.Point(100100);
dataGridView1.RowHeadersWidth=50;
dataGridView1.RowTemplate.Height=25;
dataGridView1.Size=新系统.Drawing.Size(55+50*2,25+dataGridView1.RowTemplate.Height*2);
dataGridView1.Anchor=System.Windows.Forms.AnchorStyles.None;
dataGridView1.ColumnHeadershightSizeMode=System.Windows.Forms.DataGridViewColumnHeadershightSizeMode.AutoSize;
dataGridView1.Columns.AddRange(Columns);
dataGridView1.TabIndex=3;
dataGridView1.AllowUserToAddress=false;
dataGridView1.Rows.Add();
dataGridView1.Rows.Add();
dataGridView1.Rows[0].HeaderCell.Value=“i”+1;
dataGridView1.Rows[1].HeaderCell.Value=“i”+2;
dataGridView1.Rows[0]。单元格[0]。Value=“value1”;
控件。添加(dataGridView1);
控制克隆1=克隆控制(dataGridView1);
克隆1.立根(克隆1.位置X,克隆1.位置Y+300,克隆1.宽度,ct1.高度);
控件。添加(克隆1);
cloned1.Show();
}    
公共控制克隆控制(控制ct1)
{
Hashtable PropertyList=新的Hashtable();
PropertyDescriptorCollection属性=TypeDescriptor.GetProperties(ct1);
Assembly controlAsm=Assembly.LoadWithPartialName(ct1.GetType().Namespace);
类型controlType=controlAsm.GetType(ct1.GetType().Namespace+“+ct1.GetType().Name);
Control cloned1=(Control)Activator.CreateInstance(controlType);
foreach(属性中的PropertyDescriptor pr1)
{
if(pr1.PropertyType.IsSerializable)
{
Add(pr1.Name,pr1.GetValue(ct1));
}
if(PropertyList.Contains(pr1.Name))
{
尝试
{
Object obj=PropertyList[pr1.Name];
pr1.设定值(克隆1,obj);
}
捕获(例外情况除外)
{
}
}
}
返回ct2;
}
如果你运行代码。。。你会得到的

public Form1()
{
    InitializeComponent();
        Columns = new DataGridViewTextBoxColumn[2];
        for (int i = 0; i < 2; i++)
        {
            Columns[i] = new System.Windows.Forms.DataGridViewTextBoxColumn();
            // 
            // Columns[i]
            // 
            Columns[i].HeaderText = "j" + (i + 1);
            Columns[i].Name = "Column" + (i + 1);
            Columns[i].Width = 50;
        }
        dataGridView1 = new System.Windows.Forms.DataGridView();
        dataGridView1.Name = "dataGridView1";
        dataGridView1.Location = new System.Drawing.Point(100, 100);
        dataGridView1.RowHeadersWidth = 50;
        dataGridView1.RowTemplate.Height = 25;
        dataGridView1.Size = new System.Drawing.Size(55 + 50 * 2, 25 + dataGridView1.RowTemplate.Height * 2);
        dataGridView1.Anchor = System.Windows.Forms.AnchorStyles.None;
        dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        dataGridView1.Columns.AddRange(Columns);
        dataGridView1.TabIndex = 3;
        dataGridView1.AllowUserToAddRows = false;
        dataGridView1.Rows.Add();
        dataGridView1.Rows.Add();
        dataGridView1.Rows[0].HeaderCell.Value = "i" + 1;
        dataGridView1.Rows[1].HeaderCell.Value = "i" + 2;
        dataGridView1.Rows[0].Cells[0].Value = "value1";
        Controls.Add(dataGridView1);

        Control cloned1 = CloneControl(dataGridView1); 
        cloned1.SetBounds(cloned1.Location.X, cloned1.Location.Y + 300, cloned1.Width, ct1.Height);
        Controls.Add(cloned1);
        cloned1.Show();
}    

public Control CloneControl(Control ct1)
{
    Hashtable PropertyList = new Hashtable();
    PropertyDescriptorCollection Properties = TypeDescriptor.GetProperties(ct1);
    Assembly controlAsm = Assembly.LoadWithPartialName(ct1.GetType().Namespace);
    Type controlType = controlAsm.GetType(ct1.GetType().Namespace + "." + ct1.GetType().Name);
    Control cloned1 = (Control)Activator.CreateInstance(controlType);
    foreach (PropertyDescriptor pr1 in Properties)
    {
        if (pr1.PropertyType.IsSerializable)
        {
            PropertyList.Add(pr1.Name, pr1.GetValue(ct1));
        }
        if (PropertyList.Contains(pr1.Name))
        {
            try
            {
                 Object obj = PropertyList[pr1.Name];
                 pr1.SetValue(cloned1, obj);
            }
            catch (Exception ex)
            {

            }
        }
    }
    return ct2;
}

public Form1()
{
    InitializeComponent();
        Columns = new DataGridViewTextBoxColumn[2];
        for (int i = 0; i < 2; i++)
        {
            Columns[i] = new System.Windows.Forms.DataGridViewTextBoxColumn();
            // 
            // Columns[i]
            // 
            Columns[i].HeaderText = "j" + (i + 1);
            Columns[i].Name = "Column" + (i + 1);
            Columns[i].Width = 50;
        }
        dataGridView1 = new System.Windows.Forms.DataGridView();
        dataGridView1.Name = "dataGridView1";
        dataGridView1.Location = new System.Drawing.Point(100, 100);
        dataGridView1.RowHeadersWidth = 50;
        dataGridView1.RowTemplate.Height = 25;
        dataGridView1.Size = new System.Drawing.Size(55 + 50 * 2, 25 + dataGridView1.RowTemplate.Height * 2);
        dataGridView1.Anchor = System.Windows.Forms.AnchorStyles.None;
        dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        dataGridView1.Columns.AddRange(Columns);
        dataGridView1.TabIndex = 3;
        dataGridView1.AllowUserToAddRows = false;
        dataGridView1.Rows.Add();
        dataGridView1.Rows.Add();
        dataGridView1.Rows[0].HeaderCell.Value = "i" + 1;
        dataGridView1.Rows[1].HeaderCell.Value = "i" + 2;
        dataGridView1.Rows[0].Cells[0].Value = "value1";
        Controls.Add(dataGridView1);

        Control cloned1 = CloneControl(dataGridView1); 
        cloned1.SetBounds(cloned1.Location.X, cloned1.Location.Y + 300, cloned1.Width, ct1.Height);
        Controls.Add(cloned1);
        cloned1.Show();
}    

public Control CloneControl(Control ct1)
{
    Hashtable PropertyList = new Hashtable();
    PropertyDescriptorCollection Properties = TypeDescriptor.GetProperties(ct1);
    Assembly controlAsm = Assembly.LoadWithPartialName(ct1.GetType().Namespace);
    Type controlType = controlAsm.GetType(ct1.GetType().Namespace + "." + ct1.GetType().Name);
    Control cloned1 = (Control)Activator.CreateInstance(controlType);
    foreach (PropertyDescriptor pr1 in Properties)
    {
        if (pr1.PropertyType.IsSerializable)
        {
            PropertyList.Add(pr1.Name, pr1.GetValue(ct1));
        }
        if (PropertyList.Contains(pr1.Name))
        {
            try
            {
                 Object obj = PropertyList[pr1.Name];
                 pr1.SetValue(cloned1, obj);
            }
            catch (Exception ex)
            {

            }
        }
    }
    return ct2;
}
正如您在main方法中看到的,我创建了dataGridView1的克隆,它有一些属性。
实际上,在克隆的dataGridView中,每个单元格值都是空的。 此外,列的大小也不会被克隆

public Form1()
{
    InitializeComponent();
        Columns = new DataGridViewTextBoxColumn[2];
        for (int i = 0; i < 2; i++)
        {
            Columns[i] = new System.Windows.Forms.DataGridViewTextBoxColumn();
            // 
            // Columns[i]
            // 
            Columns[i].HeaderText = "j" + (i + 1);
            Columns[i].Name = "Column" + (i + 1);
            Columns[i].Width = 50;
        }
        dataGridView1 = new System.Windows.Forms.DataGridView();
        dataGridView1.Name = "dataGridView1";
        dataGridView1.Location = new System.Drawing.Point(100, 100);
        dataGridView1.RowHeadersWidth = 50;
        dataGridView1.RowTemplate.Height = 25;
        dataGridView1.Size = new System.Drawing.Size(55 + 50 * 2, 25 + dataGridView1.RowTemplate.Height * 2);
        dataGridView1.Anchor = System.Windows.Forms.AnchorStyles.None;
        dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        dataGridView1.Columns.AddRange(Columns);
        dataGridView1.TabIndex = 3;
        dataGridView1.AllowUserToAddRows = false;
        dataGridView1.Rows.Add();
        dataGridView1.Rows.Add();
        dataGridView1.Rows[0].HeaderCell.Value = "i" + 1;
        dataGridView1.Rows[1].HeaderCell.Value = "i" + 2;
        dataGridView1.Rows[0].Cells[0].Value = "value1";
        Controls.Add(dataGridView1);

        Control cloned1 = CloneControl(dataGridView1); 
        cloned1.SetBounds(cloned1.Location.X, cloned1.Location.Y + 300, cloned1.Width, ct1.Height);
        Controls.Add(cloned1);
        cloned1.Show();
}    

public Control CloneControl(Control ct1)
{
    Hashtable PropertyList = new Hashtable();
    PropertyDescriptorCollection Properties = TypeDescriptor.GetProperties(ct1);
    Assembly controlAsm = Assembly.LoadWithPartialName(ct1.GetType().Namespace);
    Type controlType = controlAsm.GetType(ct1.GetType().Namespace + "." + ct1.GetType().Name);
    Control cloned1 = (Control)Activator.CreateInstance(controlType);
    foreach (PropertyDescriptor pr1 in Properties)
    {
        if (pr1.PropertyType.IsSerializable)
        {
            PropertyList.Add(pr1.Name, pr1.GetValue(ct1));
        }
        if (PropertyList.Contains(pr1.Name))
        {
            try
            {
                 Object obj = PropertyList[pr1.Name];
                 pr1.SetValue(cloned1, obj);
            }
            catch (Exception ex)
            {

            }
        }
    }
    return ct2;
}
您可能会有一个问题:如果Visual Studio或SharpDeveloper as IDE(用C#编写)能够处理这个问题,那么就有可能编写这种代码!对吗?
在Visual Studio中,当您尝试拖放控件或复制粘贴控件时,它不仅会使用所有属性(包括可序列化或不可序列化)复制该控件,而且还会将控件本身的名称从“dataGridView1”更改为“dataGridView2”,以及在SharpDeveloper中

public Form1()
{
    InitializeComponent();
        Columns = new DataGridViewTextBoxColumn[2];
        for (int i = 0; i < 2; i++)
        {
            Columns[i] = new System.Windows.Forms.DataGridViewTextBoxColumn();
            // 
            // Columns[i]
            // 
            Columns[i].HeaderText = "j" + (i + 1);
            Columns[i].Name = "Column" + (i + 1);
            Columns[i].Width = 50;
        }
        dataGridView1 = new System.Windows.Forms.DataGridView();
        dataGridView1.Name = "dataGridView1";
        dataGridView1.Location = new System.Drawing.Point(100, 100);
        dataGridView1.RowHeadersWidth = 50;
        dataGridView1.RowTemplate.Height = 25;
        dataGridView1.Size = new System.Drawing.Size(55 + 50 * 2, 25 + dataGridView1.RowTemplate.Height * 2);
        dataGridView1.Anchor = System.Windows.Forms.AnchorStyles.None;
        dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        dataGridView1.Columns.AddRange(Columns);
        dataGridView1.TabIndex = 3;
        dataGridView1.AllowUserToAddRows = false;
        dataGridView1.Rows.Add();
        dataGridView1.Rows.Add();
        dataGridView1.Rows[0].HeaderCell.Value = "i" + 1;
        dataGridView1.Rows[1].HeaderCell.Value = "i" + 2;
        dataGridView1.Rows[0].Cells[0].Value = "value1";
        Controls.Add(dataGridView1);

        Control cloned1 = CloneControl(dataGridView1); 
        cloned1.SetBounds(cloned1.Location.X, cloned1.Location.Y + 300, cloned1.Width, ct1.Height);
        Controls.Add(cloned1);
        cloned1.Show();
}    

public Control CloneControl(Control ct1)
{
    Hashtable PropertyList = new Hashtable();
    PropertyDescriptorCollection Properties = TypeDescriptor.GetProperties(ct1);
    Assembly controlAsm = Assembly.LoadWithPartialName(ct1.GetType().Namespace);
    Type controlType = controlAsm.GetType(ct1.GetType().Namespace + "." + ct1.GetType().Name);
    Control cloned1 = (Control)Activator.CreateInstance(controlType);
    foreach (PropertyDescriptor pr1 in Properties)
    {
        if (pr1.PropertyType.IsSerializable)
        {
            PropertyList.Add(pr1.Name, pr1.GetValue(ct1));
        }
        if (PropertyList.Contains(pr1.Name))
        {
            try
            {
                 Object obj = PropertyList[pr1.Name];
                 pr1.SetValue(cloned1, obj);
            }
            catch (Exception ex)
            {

            }
        }
    }
    return ct2;
}
我该怎么办?
我应该创建什么样的方法?
也许另一个控件有许多不可序列化的属性
如何复制它们

public Form1()
{
    InitializeComponent();
        Columns = new DataGridViewTextBoxColumn[2];
        for (int i = 0; i < 2; i++)
        {
            Columns[i] = new System.Windows.Forms.DataGridViewTextBoxColumn();
            // 
            // Columns[i]
            // 
            Columns[i].HeaderText = "j" + (i + 1);
            Columns[i].Name = "Column" + (i + 1);
            Columns[i].Width = 50;
        }
        dataGridView1 = new System.Windows.Forms.DataGridView();
        dataGridView1.Name = "dataGridView1";
        dataGridView1.Location = new System.Drawing.Point(100, 100);
        dataGridView1.RowHeadersWidth = 50;
        dataGridView1.RowTemplate.Height = 25;
        dataGridView1.Size = new System.Drawing.Size(55 + 50 * 2, 25 + dataGridView1.RowTemplate.Height * 2);
        dataGridView1.Anchor = System.Windows.Forms.AnchorStyles.None;
        dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        dataGridView1.Columns.AddRange(Columns);
        dataGridView1.TabIndex = 3;
        dataGridView1.AllowUserToAddRows = false;
        dataGridView1.Rows.Add();
        dataGridView1.Rows.Add();
        dataGridView1.Rows[0].HeaderCell.Value = "i" + 1;
        dataGridView1.Rows[1].HeaderCell.Value = "i" + 2;
        dataGridView1.Rows[0].Cells[0].Value = "value1";
        Controls.Add(dataGridView1);

        Control cloned1 = CloneControl(dataGridView1); 
        cloned1.SetBounds(cloned1.Location.X, cloned1.Location.Y + 300, cloned1.Width, ct1.Height);
        Controls.Add(cloned1);
        cloned1.Show();
}    

public Control CloneControl(Control ct1)
{
    Hashtable PropertyList = new Hashtable();
    PropertyDescriptorCollection Properties = TypeDescriptor.GetProperties(ct1);
    Assembly controlAsm = Assembly.LoadWithPartialName(ct1.GetType().Namespace);
    Type controlType = controlAsm.GetType(ct1.GetType().Namespace + "." + ct1.GetType().Name);
    Control cloned1 = (Control)Activator.CreateInstance(controlType);
    foreach (PropertyDescriptor pr1 in Properties)
    {
        if (pr1.PropertyType.IsSerializable)
        {
            PropertyList.Add(pr1.Name, pr1.GetValue(ct1));
        }
        if (PropertyList.Contains(pr1.Name))
        {
            try
            {
                 Object obj = PropertyList[pr1.Name];
                 pr1.SetValue(cloned1, obj);
            }
            catch (Exception ex)
            {

            }
        }
    }
    return ct2;
}

请任何人……

像评论中提到的@Hans一样,
克隆
并不是那么容易。如果希望得到一些相同的控件,但只是略有不同,那么最好使用函数定义一般行为,并将不同的属性作为参数传递到中。例如,我们定义了一个具有适用于DataGridView的一些常规属性的函数:

public Form1()
{
    InitializeComponent();
        Columns = new DataGridViewTextBoxColumn[2];
        for (int i = 0; i < 2; i++)
        {
            Columns[i] = new System.Windows.Forms.DataGridViewTextBoxColumn();
            // 
            // Columns[i]
            // 
            Columns[i].HeaderText = "j" + (i + 1);
            Columns[i].Name = "Column" + (i + 1);
            Columns[i].Width = 50;
        }
        dataGridView1 = new System.Windows.Forms.DataGridView();
        dataGridView1.Name = "dataGridView1";
        dataGridView1.Location = new System.Drawing.Point(100, 100);
        dataGridView1.RowHeadersWidth = 50;
        dataGridView1.RowTemplate.Height = 25;
        dataGridView1.Size = new System.Drawing.Size(55 + 50 * 2, 25 + dataGridView1.RowTemplate.Height * 2);
        dataGridView1.Anchor = System.Windows.Forms.AnchorStyles.None;
        dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        dataGridView1.Columns.AddRange(Columns);
        dataGridView1.TabIndex = 3;
        dataGridView1.AllowUserToAddRows = false;
        dataGridView1.Rows.Add();
        dataGridView1.Rows.Add();
        dataGridView1.Rows[0].HeaderCell.Value = "i" + 1;
        dataGridView1.Rows[1].HeaderCell.Value = "i" + 2;
        dataGridView1.Rows[0].Cells[0].Value = "value1";
        Controls.Add(dataGridView1);

        Control cloned1 = CloneControl(dataGridView1); 
        cloned1.SetBounds(cloned1.Location.X, cloned1.Location.Y + 300, cloned1.Width, ct1.Height);
        Controls.Add(cloned1);
        cloned1.Show();
}    

public Control CloneControl(Control ct1)
{
    Hashtable PropertyList = new Hashtable();
    PropertyDescriptorCollection Properties = TypeDescriptor.GetProperties(ct1);
    Assembly controlAsm = Assembly.LoadWithPartialName(ct1.GetType().Namespace);
    Type controlType = controlAsm.GetType(ct1.GetType().Namespace + "." + ct1.GetType().Name);
    Control cloned1 = (Control)Activator.CreateInstance(controlType);
    foreach (PropertyDescriptor pr1 in Properties)
    {
        if (pr1.PropertyType.IsSerializable)
        {
            PropertyList.Add(pr1.Name, pr1.GetValue(ct1));
        }
        if (PropertyList.Contains(pr1.Name))
        {
            try
            {
                 Object obj = PropertyList[pr1.Name];
                 pr1.SetValue(cloned1, obj);
            }
            catch (Exception ex)
            {

            }
        }
    }
    return ct2;
}
private void InitDataGridView(DataGridView dataGridView, string name)
{
    dataGridView.Name = name;

    // configure other properties here
    dataGridView.Location = new System.Drawing.Point(100, 100);
    dataGridView.RowHeadersWidth = 50;
    dataGridView.RowTemplate.Height = 25;
    dataGridView.Size = new System.Drawing.Size(55 + 50 * 2, 25 + dataGridView1.RowTemplate.Height * 2);
    dataGridView.Anchor = System.Windows.Forms.AnchorStyles.None;
    dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
    // remember to initialize your columns, or pass it in as a parameter
    dataGridView.Columns.AddRange(Columns);
    dataGridView.AllowUserToAddRows = false;
    dataGridView.Rows.Add();
    dataGridView.Rows.Add();
    dataGridView.Rows[0].HeaderCell.Value = "i" + 1;
    dataGridView.Rows[1].HeaderCell.Value = "i" + 2;
    dataGridView.Rows[0].Cells[0].Value = "value1";
}

public Form1()
{
    InitializeComponent();

    var dataGridView1 = new DataGridView();
    var dataGridView2 = new DataGridView();

    InitDataGridView(dataGridView1, "dataGridView1");
    InitDataGridView(dataGridView2, "dataGridView2");
}

就像评论中提到的@Hans一样,
Clone
并不是那么容易。如果希望得到一些相同的控件,但只是略有不同,那么最好使用函数定义一般行为,并将不同的属性作为参数传递到中。例如,我们定义了一个具有适用于DataGridView的一些常规属性的函数:

public Form1()
{
    InitializeComponent();
        Columns = new DataGridViewTextBoxColumn[2];
        for (int i = 0; i < 2; i++)
        {
            Columns[i] = new System.Windows.Forms.DataGridViewTextBoxColumn();
            // 
            // Columns[i]
            // 
            Columns[i].HeaderText = "j" + (i + 1);
            Columns[i].Name = "Column" + (i + 1);
            Columns[i].Width = 50;
        }
        dataGridView1 = new System.Windows.Forms.DataGridView();
        dataGridView1.Name = "dataGridView1";
        dataGridView1.Location = new System.Drawing.Point(100, 100);
        dataGridView1.RowHeadersWidth = 50;
        dataGridView1.RowTemplate.Height = 25;
        dataGridView1.Size = new System.Drawing.Size(55 + 50 * 2, 25 + dataGridView1.RowTemplate.Height * 2);
        dataGridView1.Anchor = System.Windows.Forms.AnchorStyles.None;
        dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        dataGridView1.Columns.AddRange(Columns);
        dataGridView1.TabIndex = 3;
        dataGridView1.AllowUserToAddRows = false;
        dataGridView1.Rows.Add();
        dataGridView1.Rows.Add();
        dataGridView1.Rows[0].HeaderCell.Value = "i" + 1;
        dataGridView1.Rows[1].HeaderCell.Value = "i" + 2;
        dataGridView1.Rows[0].Cells[0].Value = "value1";
        Controls.Add(dataGridView1);

        Control cloned1 = CloneControl(dataGridView1); 
        cloned1.SetBounds(cloned1.Location.X, cloned1.Location.Y + 300, cloned1.Width, ct1.Height);
        Controls.Add(cloned1);
        cloned1.Show();
}    

public Control CloneControl(Control ct1)
{
    Hashtable PropertyList = new Hashtable();
    PropertyDescriptorCollection Properties = TypeDescriptor.GetProperties(ct1);
    Assembly controlAsm = Assembly.LoadWithPartialName(ct1.GetType().Namespace);
    Type controlType = controlAsm.GetType(ct1.GetType().Namespace + "." + ct1.GetType().Name);
    Control cloned1 = (Control)Activator.CreateInstance(controlType);
    foreach (PropertyDescriptor pr1 in Properties)
    {
        if (pr1.PropertyType.IsSerializable)
        {
            PropertyList.Add(pr1.Name, pr1.GetValue(ct1));
        }
        if (PropertyList.Contains(pr1.Name))
        {
            try
            {
                 Object obj = PropertyList[pr1.Name];
                 pr1.SetValue(cloned1, obj);
            }
            catch (Exception ex)
            {

            }
        }
    }
    return ct2;
}
private void InitDataGridView(DataGridView dataGridView, string name)
{
    dataGridView.Name = name;

    // configure other properties here
    dataGridView.Location = new System.Drawing.Point(100, 100);
    dataGridView.RowHeadersWidth = 50;
    dataGridView.RowTemplate.Height = 25;
    dataGridView.Size = new System.Drawing.Size(55 + 50 * 2, 25 + dataGridView1.RowTemplate.Height * 2);
    dataGridView.Anchor = System.Windows.Forms.AnchorStyles.None;
    dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
    // remember to initialize your columns, or pass it in as a parameter
    dataGridView.Columns.AddRange(Columns);
    dataGridView.AllowUserToAddRows = false;
    dataGridView.Rows.Add();
    dataGridView.Rows.Add();
    dataGridView.Rows[0].HeaderCell.Value = "i" + 1;
    dataGridView.Rows[1].HeaderCell.Value = "i" + 2;
    dataGridView.Rows[0].Cells[0].Value = "value1";
}

public Form1()
{
    InitializeComponent();

    var dataGridView1 = new DataGridView();
    var dataGridView2 = new DataGridView();

    InitDataGridView(dataGridView1, "dataGridView1");
    InitDataGridView(dataGridView2, "dataGridView2");
}

我想我在这里做了更好的方法。
此方法首先检查属性的接口:如果是ICollection,则执行第一个作业。
在一个循环在方法“DeepClone()”中结束后,需要在不检查PropertyType接口的情况下执行另一个循环。。。我的意思是我不能把这两个操作混成一个循环
您还可以检测到将出现某种运行时异常,因此我将此代码放入try-catch块中

public Form1()
{
    InitializeComponent();
        Columns = new DataGridViewTextBoxColumn[2];
        for (int i = 0; i < 2; i++)
        {
            Columns[i] = new System.Windows.Forms.DataGridViewTextBoxColumn();
            // 
            // Columns[i]
            // 
            Columns[i].HeaderText = "j" + (i + 1);
            Columns[i].Name = "Column" + (i + 1);
            Columns[i].Width = 50;
        }
        dataGridView1 = new System.Windows.Forms.DataGridView();
        dataGridView1.Name = "dataGridView1";
        dataGridView1.Location = new System.Drawing.Point(100, 100);
        dataGridView1.RowHeadersWidth = 50;
        dataGridView1.RowTemplate.Height = 25;
        dataGridView1.Size = new System.Drawing.Size(55 + 50 * 2, 25 + dataGridView1.RowTemplate.Height * 2);
        dataGridView1.Anchor = System.Windows.Forms.AnchorStyles.None;
        dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        dataGridView1.Columns.AddRange(Columns);
        dataGridView1.TabIndex = 3;
        dataGridView1.AllowUserToAddRows = false;
        dataGridView1.Rows.Add();
        dataGridView1.Rows.Add();
        dataGridView1.Rows[0].HeaderCell.Value = "i" + 1;
        dataGridView1.Rows[1].HeaderCell.Value = "i" + 2;
        dataGridView1.Rows[0].Cells[0].Value = "value1";
        Controls.Add(dataGridView1);

        Control cloned1 = CloneControl(dataGridView1); 
        cloned1.SetBounds(cloned1.Location.X, cloned1.Location.Y + 300, cloned1.Width, ct1.Height);
        Controls.Add(cloned1);
        cloned1.Show();
}    

public Control CloneControl(Control ct1)
{
    Hashtable PropertyList = new Hashtable();
    PropertyDescriptorCollection Properties = TypeDescriptor.GetProperties(ct1);
    Assembly controlAsm = Assembly.LoadWithPartialName(ct1.GetType().Namespace);
    Type controlType = controlAsm.GetType(ct1.GetType().Namespace + "." + ct1.GetType().Name);
    Control cloned1 = (Control)Activator.CreateInstance(controlType);
    foreach (PropertyDescriptor pr1 in Properties)
    {
        if (pr1.PropertyType.IsSerializable)
        {
            PropertyList.Add(pr1.Name, pr1.GetValue(ct1));
        }
        if (PropertyList.Contains(pr1.Name))
        {
            try
            {
                 Object obj = PropertyList[pr1.Name];
                 pr1.SetValue(cloned1, obj);
            }
            catch (Exception ex)
            {

            }
        }
    }
    return ct2;
}
    Control cloned1 = (Control)DeepClone(dataGridView1); 
    cloned1.SetBounds(cloned1.Location.X, cloned1.Location.Y + 300, cloned1.Width, ct1.Height);
    Controls.Add(cloned1);
    cloned1.Show();




    public dynamic DeepClone(dynamic ob1)
    {
        dynamic ob2 = null;
        if (ob1.GetType().IsSerializable && !ob1.GetType().IsArray)
        {
            if (ob1 != null)
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(ms, ob1);
                    ms.Position = 0;
                    ob2 = formatter.Deserialize(ms);
                }
            }
        }
        else
        {
            if (ob1.GetType().IsArray)
            {
                var r1 = ob1.Rank;
                object[] d1 = new object[r1];
                long[] V1 = new long[r1];
                for (int i = 0; i < r1; i++)
                {
                    V1[i] = 0;
                    d1[i] = ob1.GetUpperBound(i) + 1;
                }
                ob2 = Activator.CreateInstance(ob1.GetType(), d1);
                for (long i = 0; i <= ob2.Length; i++)
                {
                    ob2.SetValue(DeepClone(ob1.GetValue(V1)), V1);
                    for (int j = 0; j <= V1.GetUpperBound(0); j++)
                    {
                        if (V1[j] < ob2.GetUpperBound(j))
                        {
                            V1[j]++;
                            break;
                        }
                        else
                        {
                            V1[j] = 0;
                        }
                    }
                }
            }
            else
            {
                PropertyInfo[] P1 = ob1.GetType().GetProperties();
                ob2 = Activator.CreateInstance(ob1.GetType());
                foreach (PropertyInfo p1 in P1)
                {
                    try
                    {
                        if (p1.PropertyType.GetInterface("System.Collections.ICollection", true) != null)
                        {
                            dynamic V2 = p1.GetValue(ob1) as IEnumerable;
                            MethodInfo gm1 = p1.PropertyType.GetMethods().Where(m => m.Name == "Add").Where(p => p.GetParameters().Count() == 1).First(f => V2[0].GetType().IsSubclassOf(f.GetParameters()[0].ParameterType) || f.GetParameters()[0].ParameterType == V2[0].GetType());
                            if (V2[0].GetType().IsSubclassOf(gm1.GetParameters()[0].ParameterType) || gm1.GetParameters()[0].ParameterType == V2[0].GetType())
                            {
                                for (int i = 0; i < V2.Count; i++)
                                {
                                    dynamic V3 = DeepClone(V2[i]);
                                    gm1.Invoke(p1.GetValue(ob2), new[] {V3});
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {

                    }
                }
                foreach (PropertyInfo p1 in P1)
                {
                    try
                    {
                        if (p1.PropertyType.IsSerializable && p1.CanWrite)
                        {
                            var v2 = p1.GetValue(ob1);
                            p1.SetValue(ob2, v2);
                        }
                        if (!p1.PropertyType.IsSerializable && p1.CanWrite)
                        {
                            dynamic V2 = p1.GetValue(ob1);
                            if (p1.PropertyType.GetMethod("Clone") != null)
                            {
                                dynamic v1 = V2.Clone();
                                p1.SetValue(ob2, v1);
                            }
                        }
                    }
                    catch (Exception ex)
                    {

                    }
                }
            }
        }
        return ob2;
    }
controlcloned1=(Control)DeepClone(dataGridView1);
克隆1.立根(克隆1.位置X,克隆1.位置Y+300,克隆1.宽度,ct1.高度);
控件。添加(克隆1);
cloned1.Show();
公共动态深度克隆(动态ob1)
{
动态ob2=null;
if(ob1.GetType().IsSerializable&&!ob1.GetType().IsArray)
{
如果(ob1!=null)
{
使用(MemoryStream ms=new MemoryStream())
{
BinaryFormatter formatter=新的BinaryFormatter();
序列化(ms,ob1);
ms.Position=0;
ob2=格式化程序。反序列化(ms);
}
}
}
其他的
{
if(ob1.GetType().IsArray)
{
var r1=ob1.秩;
对象[]d1=新对象[r1];
朗