Obtener acceso a todos los valores de un control solo con su nombre.

Buenas a todos!

Resulta que de vez en cuando, la luna y marte se alinean y nosotros los programadores tenemos que arremangarnos para resolver los líos en que nos metemos….

Uno de estos líos inocentes puede ser que “alguien” te pase un string que contiene el nombre de un control que tienes en tu formulario y te dice: “haz visible ese control que te pase….. ahh se me olvidaba, el control puede estar metido dentro de tabpanels, panels o group panels…. por lo que eso de Form.Controls(“nombredelcontrol”) no va….” -_-!

Como si fuese tan facil…. pues sip, si que lo es, 2 linea de codigo, gracias a nuestro siempre querido reflection!!!

Dim obj As Object
obj = Owner.GetType().GetField(
“_” & name,Reflection.BindingFlags.NonPublic Or _
                                                          Reflection.BindingFlags.Instance Or _
                                                          Reflection.BindingFlags.IgnoreCase).GetValue(Owner)

El primer parámetro de la función GetField es el nombre de control, se le pasa “_” porque el nombre en el ensamblado está precedido de “_”, sin este no encontrará el control.!
Con esto obj contendra nuestro objeto y podremos modificar, eliminar o cambiar todo lo que queramos, quedando reflejado en nuestro objeto real. Solo con algunas lineas más de código dejaremos nuestro código mucho más reusable….

Public Function EncontrarControl(ByVal name As String, ByVal Owner As Form) As Control
      Dim obj As Object
      Try
            obj = Owner.GetType().GetField(“_” & name,Reflection.BindingFlags.NonPublic Or _
                                                                      Reflection.BindingFlags.Instance Or _
                                                                      Reflection.BindingFlags.IgnoreCase).GetValue(Owner)

            Owner.GetType().GetFiel()
            Return (CType(obj, Control))
      Catch ex As Exception
            Return Nothing
      End Try
End Function

Y listo! solo con invocar nuestra función podemos acceder directamente a las propiedades de nuestro control y modificarlo y usarlo:

 

EncontrarControl(“Nombredelcontrol”, Form1).Visible = True

 

 

 

 Hasta la próxima.

Happy Coding!

Anuncios
Publicado en Uncategorized. Etiquetas: , . 5 Comments »

5 comentarios to “Obtener acceso a todos los valores de un control solo con su nombre.”

  1. Luis Says:

    Compañero no si esto sirve para C# ya que lo implemento pero no me funciona, si me pudieras dar una ayuda.

  2. tenerifedotnet Says:

    Buenas Luis!

    Intentaré ayudarte, puedes darme algo más de info? te da algún error, simplemente no hace nada…. o pega el codigo en c# y le hecho un vistazo a ver si te puedo hechar un cable!

  3. Luis Says:

    Gracias tenerifedotnet, mi situación es la siguiente:

    Estoy implementando un sistema con multilenguaje, entonces en el load de cada formulario instancio una clase que ejecuta unos métodos que me transcriben el lenguaje dependiendo del usuario que este logueado en el sistema, con los sistemas web no tengo ningún problema, sino que estos empiezan cuando la aplicación es windows form y los controles se encuentran dentro de otros controles como paneles. Te muestro como lo hago y se que funciona tanto para web y windows con la exepción que te expliqué:

    // Iterates throught the translations of the page
    foreach (DataRow vloRow in vlaTranslations)
    {
    // Searches the control in the page
    vloControl = pvoForm.Controls[vloRow[“ControlId”].ToString().Trim()];
    //vloControl = pvoForm.Controls.Find(vloRow[“ControlId”].ToString().Trim(), true);

    // If the control was found
    if (vloControl != null)
    {
    // The translation should be performed over a Control Property.
    if (vloRow[“ControlProperty”] != DBNull.Value)
    {
    // Translante the control property
    TranslateControlProperty(vloRow, vloControl);
    }
    // The translation should be performed over a Control Collection
    else
    {
    // Translate control collection
    TranslateItemOfCollection(vloRow, vloControl);
    }
    }
    // The control was not found
    else
    {
    // Throw an exception
    throw new Exception(string.Format(CONTROL_NOT_FOUND, vloRow[“ControlId”].ToString().Trim(), vlcPageName));
    }
    }

    El método anterior busca dentro del formulario pasado por parámetro de la siguiente manera

    Formulario.Controls[NombreControl] != Null

    Quiere decir que el control existe y llamo al método que setea la propiedad Text, pasandole el objeto, la propiedad en formato String y el nuevo valor que debe llevar

    public static void SetPropertyValue(object pvoObject, string pvcProperty, object pvcValue)
    {
    // Para almacenar la lista de propiedades para llegar a la propiedad a actualizar
    string[] vlaProperties;
    // Para almacenra una propiedad
    System.Reflection.PropertyInfo vloProperty;

    try
    {
    // Obtener la lista de propiedades para llegar a la propiedad a modificar
    vlaProperties = pvcProperty.Split(new char[] { ‘.’ }, StringSplitOptions.RemoveEmptyEntries);

    // Para cada uno de de los nombres de las propiedades anteriores a la final
    for (int i = 0; i < vlaProperties.Length – 1; i++)
    {
    // Obtener la información de la propiedad
    vloProperty = pvoObject.GetType().GetProperty(vlaProperties[i]);

    // Obtener el objeto que referencia la propiedad
    pvoObject = vloProperty.GetValue(pvoObject, null);
    }

    // Obtener la propiedad a modificar
    vloProperty = pvoObject.GetType().GetProperty(vlaProperties[vlaProperties.Length – 1]);

    // Modificar el valor de la propiedad
    vloProperty.SetValue(pvoObject, pvcValue, null);
    }
    catch (Exception vloException)
    {
    // Lanzar una excpeción
    throw new Exception(string.Format(PROPERTY_NOT_FOUND, pvcProperty, “”, “”));
    }
    }

    Cuando se presentan controles que estan dentro de un panel:

    Formulario.Controls[NombreControl] != Null

    Esto siempre me devuelve Null, indicandome que el control no existe. Por lo que lo cambio por :

    Formulario.Controls.Find[NombreControl] != Null

    Ya con la linea anterior si me encuentra los controles que tengo dentro de otros controles, pero a la hora de llamar al metodo donde envio el objeto, la propiedad y el nuevo valor, me indica que la propiedad no existe. Por lo que estoy llevando a cabo una investigación para dar una solución a mi problema.

    Intento utilizar tu método pero me da tres problemas:

    public static Control EncontrarControl(String pvcNombreControl, Form pvoFormulario)
    {
    Object obj;
    try
    {
    obj = pvoFormulario.GetType().GetField(“_” + pvcNombreControl, System.Reflection.BindingFlags.NonPublic |
    System.Reflection.BindingFlags.Instance |
    System.Reflection.BindingFlags.IgnoreCase).GetValue(pvoFormulario);
    pvoFormulario.GetType().GetField();

    return (Convert.ChangeType(obj, Control));

    }
    catch (Exception vloException)
    {
    return null;
    }
    }

    La línea siguiente:

    pvoFormulario.GetType().GetField();
    Error: Sobre carga de métodos, cero argumentos.

    return (Convert.ChangeType(obj, Control));
    Error: Control es un tipo y esta siendo usado como variable

    por lo que lo intento utilizar de la siguiente manera:

    public static Object EncontrarControl(String pvcNombreControl, Form pvoFormulario)
    {
    Object obj;
    try
    {
    obj = pvoFormulario.GetType().GetField(“_” + pvcNombreControl, System.Reflection.BindingFlags.NonPublic |
    System.Reflection.BindingFlags.Instance |
    System.Reflection.BindingFlags.IgnoreCase).GetValue(pvoFormulario);
    return obj;
    }
    catch (Exception vloException)
    {
    return null;
    }
    }

    Pero la línea siguiente:

    obj = pvoFormulario.GetType().GetField(“_” + pvcNombreControl, System.Reflection.BindingFlags.NonPublic |
    System.Reflection.BindingFlags.Instance |
    System.Reflection.BindingFlags.IgnoreCase).GetValue(pvoFormulario);

    Me dispara el siguiente error:

    Object reference not set to an instance of an object

    Por lo que no puedo ejecutar el método.

    Espero que con esto puedas entender y me puedas brindar algún tipo de ayuda, gracias de antemano.

  4. Luis Says:

    tenerifedotnet te comunico que investigando un travesiando un poco más encontre la solución a mi problema con la ayuda de tu método, te muestro la implementación y muchas gracias.

    public static Control EncontrarControl(String pvcNombreControl, Form pvoFormulario)
    {
    Object obj;
    try
    {
    System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic |
    System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance;

    Type t = pvoFormulario.GetType();

    System.Reflection.FieldInfo fi = t.GetField(pvcNombreControl, flags);

    return ((Control)fi.GetValue(pvoFormulario));
    }
    catch (Exception vloException)
    {
    return null;
    }
    }

    • tenerifedotnet Says:

      Buenas tardes Luis!

      Me alegra mucho que encontrases la solución al problema, y me alegra haberte ayudado un poco! gracias por visitarnos, espero poder volver a publicar algun articulo en breve.

      Un saludo muy grande!!!


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: