Lilypie Primer PicLilypie Primer Ticker

martes, 6 de febrero de 2007

Clonar un Control

En uno de los foros en que participo, un colega preguntó cual era la forma de crear copias idénticas ('clones') de una Caja de Edición (TextBox) en tiempo de ejecución. Intenté ver si los controles incluían algún constructor que tomara un parámetro tipo Control y creara una copia a partir de éste, lamentablemente los controles no incluyen tal constructor (pienso que sería útil)

Aqui planteo la forma de crear 'clones' de un control (en realidad, de cualquier objeto), usando Reflection.

Versión C#

private void Clonar(object src, object tgt)
{
PropertyInfo[] props = src.GetType().GetProperties();
foreach (PropertyInfo pi in props)
{
if (pi.CanWrite)
pi.SetValue(tgt, pi.GetValue(src, null), null);
}
}

No hay que olvidar incluir un using System.Reflection

Asumamos que hemos creado un TextBox llamado tbOriginal y hemos personalizado el tipo de letra, el tamaño, etc. Si queremos crear una copia idéntica usando el método Clonar definido antes, usariamos algo asi:

TextBox tbClon = new TextBox();
Clonar (tbOriginal, tbClon);

ya tenemos la copia, y solo nos quedaría modificar la posición, y añadirlo al Form

tbClon.Top += 20;
this.Controls.Add(tbClon);

Como la consulta fue hecha en un foro de VB.NET, también aqui esta la traducción. Me llevó mas tiempo traducir el código que escribir la función :) VB nunca fue mi lenguaje favorito. Aqui está el código para quien le pudiera interesar


Private Sub Clonar(ByVal src As Object, ByVal tgt As Object)
Dim props As System.Reflection.PropertyInfo()
props = src.GetType().GetProperties()
For Each pi As System.Reflection.PropertyInfo In props
If pi.CanWrite Then
pi.SetValue(tgt, pi.GetValue(src, Nothing), Nothing)
End If
Next
End Sub


Hasta la próxima

6 comentarios:

Anónimo dijo...

No me ha resultado el método me sale un error:
"Se produjo una excepción en el destino de la invocación"
tienes alguna idea de por que sucede esto??
esperando tus comentarios
Marcelo
mparrag@gmail.com

J. Marcos Troncoso dijo...

Hola Marcelo

Parece ser que se trata de una referencia nula, o algo asi.

Podrias indicarme que lenguaje estás utilizando y cuál linea es la que te lanza el error??

Apenas tenga esa información veré cual es el problema.

Saludos

Anónimo dijo...

Para clonar objetos se debe implementar la interfaz IClonable, que agrega el metodo Clone al objeto que se desea clonar.

J. Marcos Troncoso dijo...

Hola Yerba,

Totalmente de acuerdo: implementar ICloneable es una forma de darle capacidades de clonación a nuestras clases. Necesitariamos por tanto implementar esta interfaz en cada Clase que escribamos.

Sin embargo, al usar Reflection de la manera aqui planteada nos permite contar con un mecanismo aplicable a cualquier clase, sin necesidad de que _cada_ clase tenga que implementar su propia clonación.

Saludos

Johntzy dijo...

Oye Sabes porque no funciona con el control Button???

Lo hice para el Textbox y funciona perfecto.

Soy principiante en C# y es el lenguaje que estoy usando, no me marca ningun error, solamente no aparece el boton clonado

NAYAN dijo...

Hola. Intente hacerlo con un PictureBox y no funcionó. Igual que Jonhnzy, no hay error, solo que no lo muestra. Podrias ayudarme? Gracias