none
Usar un objeto de un formulario en otro RRS feed

  • Pregunta

  • Tengo dos formularios, en el frmPrincipal el usuario hace click en cualquier fila de una tabla mostrada en un dgv y el programa guarda un número entero con el ID (primera columna) de la fila elegida.

    Esa información se guarda en un objeto. Lo que no puedo lograr es poder usar esa información en el formulario frmElecciones (que aparece en pantalla despues de que el usuario hace click en la tabla de frmPrincipal) para darsela como argumento al metodo que va a llenar el dgv de este nuevo frmElecciones.

    El método funciona correctamente, ya que durante la depuración le pude asignar un valor y ver como se llenaba correctamente la tabla.

    Vi varias veces diferentes explicaciones de como compartir objetos entre formularios pero no puedo replicarlo en mi codigo. Les dejo los codigos de ambos formularios:

    FRMPRINCIPAL:

    namespace Presentacion
    {
        public partial class frmPrograma : Form
        {
            private DataTable dt = new DataTable();
            private DataSet ds = new DataSet();
            public Entidades.Alumno objEntidadAlumno = new Entidades.Alumno();
    
    
    
            public frmPrograma()
            {
            
    
            InitializeComponent();
                Logica.Alumno objLogicaAlumno = new Logica.Alumno();
    
                dt = objLogicaAlumno.TraerTodos();
                ds.Tables.Add(dt);
                dgvAlumnoQueElige.DataSource = dt;
    
            }
    
            public void dgvAlumnoQueElige_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
            {
    
                //Abra un nuevo formulario con dos dgv
                //Crear instancia del form a mostrar
                frmElecciones objForm = new frmElecciones();
    
                //Que muestre en el centro de la pantalla
                objForm.StartPosition = FormStartPosition.CenterScreen;
    
                //Mostrar el form
                objForm.Show();
    
                //A la vez tome el valor del ID de la fila seleccionada 
                int IDseleccionado = Convert.ToInt32(dgvAlumnoQueElige.CurrentRow.Cells[0].Value.ToString().TrimEnd());
                //crear un objeto con el ID
    
    
                objEntidadAlumno.ID = IDseleccionado; //COMO PASO ESTE OBJETO A EL OTRO FORMULARIO?
    
    
    
    
    
            }
        }
    }

    FRM ELECCIONES:

    namespace Presentacion
    {
        public partial class frmElecciones : Form
        {
            private DataTable dt = new DataTable();
            private DataSet ds = new DataSet();
    
            public frmElecciones()
            {
                InitializeComponent();
                Logica.Eleccion objLogicaEleccion = new Logica.Eleccion();
                Entidades.Alumno pAlumno = new Entidades.Alumno();
    
    
    
                dt = objLogicaEleccion.MostrarEleccionesAlumno(pAlumno); 
                //este pAlumno esta vacio, tengo que usar el objEntidadAlumno del otro form
                ds.Tables.Add(dt); //esto puede estar de más
                dgvEleccionesDelAlumno.DataSource = dt;
            }
    
    
        }
    }

    Muchas gracias a todos los que me ayudaron en la pregunta anterior, pero me sigo trabando mucho en esto. En estos dias pude comprobar que efectivamente el objeto pAlumno estaba vacio y enviaba el ID=0, pero no puedo usar el objEntidadAlumno que tiene cargado el idSeleccionado en el frmElecciones.

    sábado, 7 de diciembre de 2019 22:33

Respuestas

  • Hola Santiago

    Ya te lo respondí en el otro thread ... 

    Vos tenes un Form padre o principal, y uno o varios Form hijos (por ej frmElecciones)

    El objeto que queres poder acceder en cualquier Form hijo lo declaras public en el Form padre, y cuando mostras un Form hijo con el método ShowDialog(), le pasas this (que es una referencia al Form principal) al mismo como parámetro, así:

    frmElecciones.ShowDialog(this);   // this es la ref. al Form principal, que es donde va esto

    Luego dentro del frmElecciones, en el método del mismo en el que tenes que acceder al objeto del principal

    frmPrincipal owner = (frmPrincipal)this.Owner;

    owner.objeto = algo;   // para asignarle algo

    algo = owner.objeto;   // para leer lo que hay

    'objeto' creo que es, en tu caso, objEntidadAlumno

    Saludos

    Pablo

    domingo, 8 de diciembre de 2019 0:42
  • Si haces lo del Owner en el método constructor de frmElecciones te va a dar null porque todavía no invocaste a ShowDialog() que es donde le pasas this, que es la referencia al frmPrograma. O sea se ejecuta el constructor de frmElecciones ANTES de que llamas a ShowDialog(this) por eso, Owner todavia es igual a null ...

    Podes hacer eso mismo en un Evento Load del frmElecciones ...

    domingo, 8 de diciembre de 2019 17:13

Todas las respuestas

  • Hola Santiago

    Ya te lo respondí en el otro thread ... 

    Vos tenes un Form padre o principal, y uno o varios Form hijos (por ej frmElecciones)

    El objeto que queres poder acceder en cualquier Form hijo lo declaras public en el Form padre, y cuando mostras un Form hijo con el método ShowDialog(), le pasas this (que es una referencia al Form principal) al mismo como parámetro, así:

    frmElecciones.ShowDialog(this);   // this es la ref. al Form principal, que es donde va esto

    Luego dentro del frmElecciones, en el método del mismo en el que tenes que acceder al objeto del principal

    frmPrincipal owner = (frmPrincipal)this.Owner;

    owner.objeto = algo;   // para asignarle algo

    algo = owner.objeto;   // para leer lo que hay

    'objeto' creo que es, en tu caso, objEntidadAlumno

    Saludos

    Pablo

    domingo, 8 de diciembre de 2019 0:42
  • Hola Santiago.Martinez25:

    Otra opción es sobrecargar el constructor del frmElecciones con un objeto del tipo Alumno:

    Esta clase sería tú clase alumno. Solo he implementado estos métodos como ejemplo.

    public class Alumno
    {
        public int Id { get; set; }
    
        public int Edad { get; set; }
    
        public string Nombre { get; set; }
    
        public Alumno()
        {
        }
    
        public DataTable TraerTodos()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("Id", typeof(int)));
            dt.Columns.Add(new DataColumn("Edad", typeof(int)));
            dt.Columns.Add(new DataColumn("Nombre", typeof(string)));
    
            dt.Rows.Add(1, 25, "Bea");
            dt.Rows.Add(2, 29, "Lisa");
            dt.Rows.Add(3, 47, "José");
            dt.Rows.Add(4, 55, "Eloy");
            dt.Rows.Add(5, 66, "Eva");
            return dt;
        }
    
        public Alumno(int id)
        {
            this.Id = id;
            this.Edad = 35;
            this.Nombre = "Defecto";
        }
    
        public override string ToString()
        {
            return String.Format("El alumno tipo tiene por ID: {0}, de edad {1}, y de nombre {2}", this.Id, this.Edad, this.Nombre);
        }
    
        
    }

    En frmPrograma el cambio esta en el evento dobleClick de dgvAlumnoQueElige

    public partial class frmPrograma : Form
    {
        private DataTable dt = new DataTable();
        private DataSet ds = new DataSet();
     //   public Entidades.Alumno objEntidadAlumno = new Entidades.Alumno();
    
        public frmPrograma()
        {
            InitializeComponent();
            Logica.Alumno objLogicaAlumno = new Logica.Alumno();
            dt = objLogicaAlumno.TraerTodos();
            ds.Tables.Add(dt);
            dgvAlumnoQueElige.DataSource = dt;
    
        }
    
        private void dgvAlumnoQueElige_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            //A la vez tome el valor del ID de la fila seleccionada 
            int IDseleccionado = Convert.ToInt32(dgvAlumnoQueElige.CurrentRow.Cells[0].Value.ToString().TrimEnd());
            //crear un objeto con el ID
    
            Logica.Alumno objEntidadAlumno = new Logica.Alumno(IDseleccionado);
    
            // tengo el alumno en un objeto. de ese tipo .
    
            //Abra un nuevo formulario con dos dgv
            //Crear instancia del form a mostrar
            frmElecciones objForm = new frmElecciones(objEntidadAlumno);
    
            //Que muestre en el centro de la pantalla
            objForm.StartPosition = FormStartPosition.CenterScreen;
            
            //Mostrar el form
            objForm.Show();
            
        }
    }

    La llamada al form de elecciones, tiene como parámetro un objeto de tipo Alumno. Ese objeto de tipo alumno, yo lo he creado en una sobrecarga del constructor de alumnos, porque no se si viene de una base de datos, o de cualquier otro modo. Lo importante es que en el frmPrograma, tengo un objeto Alumno. Ahora cuando se llama a frmElecciones, en el new frmElecciones le paso una referencia a ese objeto Alumno.

    public partial class frmElecciones : Form
    {
        public frmElecciones()
        {
            InitializeComponent();
        }
    
        public frmElecciones(int idAlumno)
        {
    
            InitializeComponent();
            MessageBox.Show("alumno elegido " + idAlumno);
    
        }
    
        public frmElecciones(Logica.Alumno alumnno)
        {
            InitializeComponent();
            MessageBox.Show(alumnno.ToString());
        }
    }
    

    Ahora frmElecciones como entra por el segundo constructor, tiene el objeto alumno y ya puede interaccionar con el.


    Espero te ayude

    domingo, 8 de diciembre de 2019 6:35
  • Hola Santiago

    Ya te lo respondí en el otro thread ... 

    Vos tenes un Form padre o principal, y uno o varios Form hijos (por ej frmElecciones)

    El objeto que queres poder acceder en cualquier Form hijo lo declaras public en el Form padre, y cuando mostras un Form hijo con el método ShowDialog(), le pasas this (que es una referencia al Form principal) al mismo como parámetro, así:

    frmElecciones.ShowDialog(this);   // this es la ref. al Form principal, que es donde va esto

    Luego dentro del frmElecciones, en el método del mismo en el que tenes que acceder al objeto del principal

    frmPrincipal owner = (frmPrincipal)this.Owner;

    owner.objeto = algo;   // para asignarle algo

    algo = owner.objeto;   // para leer lo que hay

    'objeto' creo que es, en tu caso, objEntidadAlumno

    Saludos

    Pablo

    Intente de esta forma y me funcionó, pero ahora tengo el siguiente problema:

    Si bien logro que el objEntidadAlumno.ID tenga el valor que quiero:

    Cuando el programa continua me aparece este error:

    perdon pero no entiendo porque me figura esto, si el objeto ya existe cuando el programa pasa por esta parte.

    domingo, 8 de diciembre de 2019 7:12
  • Si haces lo del Owner en el método constructor de frmElecciones te va a dar null porque todavía no invocaste a ShowDialog() que es donde le pasas this, que es la referencia al frmPrograma. O sea se ejecuta el constructor de frmElecciones ANTES de que llamas a ShowDialog(this) por eso, Owner todavia es igual a null ...

    Podes hacer eso mismo en un Evento Load del frmElecciones ...

    domingo, 8 de diciembre de 2019 17:13
  • Muchisimas gracias Tigre Pablito, en este proceso estoy aprendiendo muchisimo y ahora se agrego otro concepto para mi que es el orden de ejecución de las lineas de codigo.

    Por fin pude avanzar y fue en gran parte gracias a tu ayuda. Dejo una foto con el resultado:

    domingo, 8 de diciembre de 2019 18:41