es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Obtener elementos de ListView desde la clase Designer en WinForms utilizando Reflection en C#.

No estoy seguro si estoy en el camino correcto para probar este concepto. Aquí está la situación que estoy tratando de resolver.

Tengo un proyecto WinForms (VB.Net) y hay un formulario llamado frmMain.vb. Tiene una clase de diseño llamada frmMain.Designer.vb. He colocado un control ListView en ese formulario y he establecido una colección de elementos estáticos en su propiedad Items.

Estoy llamando a esta biblioteca de formularios WinForm en una aplicación de consola C# utilizando Reflection. Quiero obtener la lista de elementos de ese ListView en particular.

Assembly AssemblyObject = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "/WinForms.exe");
if (AssemblyObject != null)
{
    Type ExceptedType = AssemblyObject.GetTypes().ToList().Where(a => a.Name == "frmMain").FirstOrDefault();

    if (ExceptedType != null)
    {

        MemberInfo members = ((TypeInfo)ExceptedType).DeclaredMembers.Where(x => x.Name == "ListView").FirstOrDefault();
    }
}
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Según el fragmento de código proporcionado, parece que el enfoque utilizado para obtener la lista de elementos del control ListView no es correcto.

    En primer lugar, la propiedad DeclaredMembers de la clase TypeInfo devuelve todos los miembros declarados o heredados por el tipo especificado. Esto incluye campos, métodos, constructores, propiedades y eventos. Por lo tanto, es posible que no sea la propiedad deseada para obtener el control ListView.

    En su lugar, puedes utilizar el método GetField de la clase Type para obtener el objeto FieldInfo que representa el control ListView del formulario frmMain. Luego, puedes utilizar reflexión para obtener el valor de la propiedad Items.

    Aquí tienes un fragmento de código actualizado que demuestra este enfoque:

    Assembly assemblyObject = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "/WinForms.exe");
    if (assemblyObject != null)
    {
        Type expectedType = assemblyObject.GetTypes().FirstOrDefault(t => t.Name == "frmMain");
    
        if (expectedType != null)
        {
            // Obtener el campo que representa el control ListView
            FieldInfo listViewField = expectedType.GetField("listView1", BindingFlags.NonPublic | BindingFlags.Instance);
            if (listViewField != null)
            {
                // Obtener la instancia del control ListView a partir de la instancia del formulario
                object formInstance = Activator.CreateInstance(expectedType);
                ListView listView = listViewField.GetValue(formInstance) as ListView;
    
                if (listView != null)
                {
                    // Obtener los elementos del control ListView
                    foreach (ListViewItem item in listView.Items)
                    {
                        Console.WriteLine(item.Text);
                    }
                }
            }
        }
    }
    

    Ten en cuenta que en el código anterior, asumí que la propiedad Name del control ListView en el formulario frmMain es listView1. Debes reemplazarlo con el nombre real si es diferente en tu código.

Comments are closed.