¿Es posible copiar todas las propiedades de un cierto control? (Formas de ventana C #)

Por ejemplo, tengo un control DataGridView con una propiedad Blue BackgroundColor , etc., ¿hay alguna manera de transferir o pasar estas propiedades programáticamente a otro control DataGridView ?

Algo como esto:

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

Gracias…

Necesitarás usar reflexión.

Obtiene una referencia a cada propiedad en su control fuente (según su tipo), luego “obtiene” su valor, asignando ese valor a su control objective.

Aquí hay un ejemplo crudo:

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

Puede usar el reflection para obtener todas las propiedades públicas del tipo y copiar los valores de una instancia a otra, pero esto es peligroso y puede que no duplique realmente el estado completo del objeto. Es posible que haya algunas propiedades que no desea copiar (por ejemplo, Parent, Site) y otras propiedades importantes que no puede establecer directamente (por ejemplo, Columns, Filas). Además, podría haber propiedades que son tipos de referencia; su control copiado terminaría haciendo referencia al mismo objeto que su original, lo que podría ser indeseable. También podría haber información de estado que solo se puede establecer a través de llamadas a métodos, que no se copiarán de esta manera. En resumen, la reflexión probablemente no sea la solución que estás buscando.

Puede que tenga que copiar manualmente las propiedades que desea. Alternativamente, podría crear un método de fábrica que pueda crear cualquier cantidad de cuadrículas similares.

Publiqué un proyecto de demostración en codeproject sobre cómo copiar y pegar o clonar un contorl hace unos años, http://www.codeproject.com/Articles/12976/How-to-Clone-Serialize-Copy-Paste-a-Windows- Formularios

Aquí está el código que se me ocurrió. Solo lo he probado con los controles Label, TextBox, Panel y DataGridView. Para un control de panel obtendrá todos los controles contenidos (instancias clonadas). Para un control DataGridView obtendrá el enlace de datos y serán exactamente los mismos datos que están vinculados al control DataGridView de origen. Por supuesto, si no hay un enlace, entonces la instancia clonada no tendrá ningún enlace. Si estos comportamientos son deseables o no depende de sus necesidades.

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

Basado en este post aquí hay una versión que

  • crea los tipos de control correctos y
  • lo hace recursivamente

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

Es posible que desee probar si se debe filtrar más de la propiedad WindowTarget .

A un lado: si el control para clonar es (on) un TabPage no seleccionado , será invisible.

Usé esto:

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

Utilicé el código siguiente para copiar las propiedades seleccionadas.

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