【发布时间】:2014-10-03 09:04:10
【问题描述】:
如何克隆或序列化 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;
}
如果你运行代码......你会得到
正如您在 main 方法中看到的,我创建了 dataGridView1 的克隆,它具有一些属性。
实际上,克隆的 dataGridView 中的每个单元格值都是空的。
列的大小也不会被克隆!
您可能有一个疑问:如果用 C# 编写的 Visual Studio 或 SharpDeveloper 作为 IDE 可以处理这个问题,那么编写这种代码是可能的!对吧?
在 Visual Studio 中,当您尝试拖放控件或复制和粘贴控件时,它不仅会复制具有所有属性(包括可序列化或不可序列化)的控件,还会将控件本身的名称从“dataGridView1”更改为“ dataGridView2" 以及在 SharpDeveloper 中!
我该怎么办?
我应该创建什么样的方法?
也许另一个控件有许多不可序列化的属性!
如何复制所有这些?
请任何人.....
【问题讨论】:
-
克隆控件是失败的鲸鱼。 Control 类具有数百个 属性和字段,其中许多严重依赖于运行时状态。您甚至无法参加活动,它们被小心地隐藏在墙后。创建一个 TextBox 总是用代码完成的。只需重新运行该代码以获取另一个代码。您可能必须从 InitializeComponent() 方法中删除该代码的明确要求。
-
忘记事件...
-
您的方向正确,只需在 IsSerializable 上放一个 else 并注意您缺少许多重要的属性。
-
也许这篇文章对你有一些帮助codeproject.com/Articles/12976/…
-
一个没人问过的问题。你为什么要这样做呢?没有人试图这样做。如果要复制表单,通常会共享控件和数据模型。创建表单的克隆,我不太确定你为什么要这样做
标签: c# winforms serialization clone deep-copy