c# - 是否可以复制某个控件的所有属性?(C# 窗口窗体)

admin 5896次浏览

摘要:8 回答 8 This answer is useful 6 你需要使用反射。 您获取对源控件中每个属性的引用(基于其类型),然后“获取”其值 - 将该值分配给目标控件。

8 回答 8

This answer is useful

6

你需要使用反射。

您获取对源控件中每个属性的引用(基于其类型),然后“获取”其值 - 将该值分配给目标控件。

这是一个粗略的例子:

private void copyControl(Control sourceControl, Control targetControl)

{

// make sure these are the same

if (sourceControl.GetType() != targetControl.GetType())

{

throw new Exception("Incorrect control types");

}

foreach (PropertyInfo sourceProperty in sourceControl.GetType().GetProperties())

{

object newValue = sourceProperty.GetValue(sourceControl, null);

MethodInfo mi = sourceProperty.GetSetMethod(true);

if (mi != null)

{

sourceProperty.SetValue(targetControl, newValue, null);

}

}

}

于 2010-08-13T03:38:16.550 回答

This answer is useful

3

您可以使用反射来获取该类型的所有公共属性并将值从一个实例复制到另一个实例,但这很危险,并且可能不会真正复制对象的整个状态。可能有一些您不想复制的属性(例如 Parent、Site),以及您无法直接设置的其他重要属性(例如 Columns、Rows)。此外,可能存在引用类型的属性;您复制的控件最终会引用与原始控件相同的对象,这可能是不可取的。也可能存在只能通过方法调用设置的状态信息,不会以这种方式复制。简而言之,反射可能不是您正在寻找的解决方案。

您可能只需要手动复制所需的属性。或者,您可以创建一个可以创建任意数量的类似网格的工厂方法。

于 2010-08-13T03:21:48.000 回答

This answer is useful

2

几年前,我在 codeproject 上发布了一个关于如何复制和粘贴或克隆 contorl 的演示项目,

http://www.codeproject.com/Articles/12976/How-to-Clone-Serialize-Copy-Paste-a-Windows-形式

于 2013-10-18T05:40:52.343 回答

This answer is useful

1

这是我想出的代码。我只使用 Label、TextBox、Panel 和 DataGridView 控件对其进行了测试。对于 Panel 控件,您将获得所有包含的控件(克隆实例)。对于 DataGridView 控件,您将获得数据绑定,它将与绑定到源 DataGridView 控件的数据完全相同。当然,如果没有绑定,那么克隆的实例将没有绑定。这些行为是否可取取决于您的需求。

private Control CloneControl(Control srcCtl)

{

var cloned = Activator.CreateInstance(srcCtl.GetType()) as Control;

var binding = BindingFlags.Public | BindingFlags.Instance;

foreach(PropertyInfo prop in srcCtl.GetType().GetProperties(binding))

{

if (IsClonable(prop))

{

object val = prop.GetValue(srcCtl);

prop.SetValue(cloned, val, null);

}

}

foreach(Control ctl in srcCtl.Controls)

{

cloned.Controls.Add(CloneControl(ctl));

}

return cloned;

}

private bool IsClonable(PropertyInfo prop)

{

var browsableAttr = prop.GetCustomAttribute(typeof(BrowsableAttribute), true) as BrowsableAttribute;

var editorBrowsableAttr = prop.GetCustomAttribute(typeof(EditorBrowsableAttribute), true) as EditorBrowsableAttribute;

return prop.CanWrite

&& (browsableAttr == null || browsableAttr.Browsable == true)

&& (editorBrowsableAttr == null || editorBrowsableAttr.State != EditorBrowsableState.Advanced);

}

于 2017-01-18T18:49:21.973 回答

This answer is useful

0

我使用下面的代码来复制选定的属性。

public static void CloneControl(Control SourceControl, Control DestinationControl)

{

String[] PropertiesToClone = new String[] { "Size", "Font", "Text", "Tag", "BackColor", "BorderStyle", "TextAlign", "Width", "Margin" };

PropertyInfo[] controlProperties = SourceControl.GetType().GetProperties();

foreach (String Property in PropertiesToClone)

{

PropertyInfo ObjPropertyInfo = controlProperties.First(a => a.Name == Property);

ObjPropertyInfo.SetValue(DestinationControl, ObjPropertyInfo.GetValue(SourceControl));

}

}

于 2016-12-27T12:01:26.130 回答

This answer is useful

0

基于这篇文章,这里是一个版本

创建正确的控件类型和

递归地这样做

public static class ControlExtensions

{

public static T Clone(this T controlToClone) where T : Control

{

PropertyInfo[] controlProperties =

typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

//T instance = Activator.CreateInstance();

Control instance = (Control) Activator.CreateInstance(controlToClone.GetType());

foreach (PropertyInfo propInfo in controlProperties)

{

if (propInfo.CanWrite)

{

if (propInfo.Name != "WindowTarget")

propInfo.SetValue(instance,

propInfo.GetValue(controlToClone, null), null);

}

}

foreach(Control ctl in controlToClone.Controls)

{

instance.Controls.Add( ctl.Clone() );

}

return (T) instance;

}

}

您仍然可能想测试是否WindowTarget应该过滤掉更多的属性..

有趣的是:如果要克隆的控件(打开)未选中 TabPage,它将不可见..

于 2017-05-31T10:29:56.597 回答

This answer is useful

0

我用这个:

Control NewControl=new Control(ControlToClone,ControlToClone.Name);

于 2017-10-24T12:30:02.343 回答

This answer is useful

0

在设计器中设置了所有属性后,我想将所有这些配置复制到另一个 DataGridView,我遇到了同样的问题。我解决了它检查 InitializeComponent(); 表格的一部分。很容易找到我设置的所有属性,并通过代码再次将其设置到另一个 DataGridView 控件。

例如,我设置了:

DataGridViewCellStyle dgvCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();

dgvCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;

dgvCellStyle1.BackColor = System.Drawing.SystemColors.Window;

dgvCellStyle1.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));

dgvCellStyle1.ForeColor = System.Drawing.SystemColors.ControlText;

dgvCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;

dgvCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;

dgvCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.False;

dgv.DefaultCellStyle = dgvCellStyle1;

dgv.GridColor = System.Drawing.SystemColors.ControlLight;

dgv.Location = new System.Drawing.Point(258, 315);

dgv.ReadOnly = true;

dgv.RowHeadersVisible = false;

dgv.RowTemplate.Height = 18;

dgv.ShowEditingIcon = false;

于 2020-12-03T17:27:43.810 回答

相关文章
友情链接