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

例如,我有一个DataGridView控件与蓝色BackgroundColor属性等..是否有一种方法,我可以传递或编程传递这些属性到另一个DataGridView控件?

像这样的东西:

 dtGrid2.Property = dtGrid1.Property; // but of course, this code is not working 

谢谢…

你需要使用reflection。

您可以获取源控件中每个属性的引用(根据其types),然后“获取”其值 – 将该值分配给目标控件。

这是一个简单的例子:

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

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

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

我在codeproject上发布了一个关于如何在几年前复制粘贴或克隆控件的演示项目, http://www.codeproject.com/Articles/12976/How-to-Clone-Serialize-Copy-Paste-a-Windows-forms

我用这个代码来克隆控制,因为我想复制只有选定的属性。

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

这是我想出来的代码。 我只用Label,TextBox,Panel和DataGridView控件testing过它。 对于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); } 

基于这个职位这里是一个版本

  • 创build正确的控件types和
  • 这样做是recursion的

 public static class ControlExtensions { public static T Clone<T>(this T controlToClone) where T : Control { PropertyInfo[] controlProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); //T instance = Activator.CreateInstance<T>(); 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; } } 

你仍然可能想testing是否应该过滤掉WindowTarget属性。

有趣的是:如果要克隆的控件是( 未选定的 TabPage ,它将不可见。

我用这个:

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