Saltar al contenido principal

 none
Acceder a control de un formulario hijo RRS feed

  • Pregunta

  • Hola a todos, tengo un formulario padre llamado frmPrincipal y otro hijo llamado frmCliente. En el formulario cliente tengo también un datagridview llamado dgCliente.

    Lo que intento hacer es que cuando tenga abierto el formulario hijo, desde el formulario padre al hacer clic sobre un botón llamado por ejemplo btEliminar, elimine el row seleccionado en el dgCliente que está en el formulario hijo, todo ello mediante:

                DialogResult dr = MessageBox.Show(this, "¿Seguro que desea eliminar el cliente?", "Eliminar cliente", MessageBoxButtons.YesNo,
                     MessageBoxIcon.Question);
                if (dr == DialogResult.Yes)
                {
                    frmClientesMDI formularioCliente = (frmClientesMDI)this.MdiParent;
                    formularioCliente.dgClientes.Rows.Remove(formularioCliente.dgClientes.CurrentRow);
                }

    El problema es que no puede acceder tan simple como:

    frmClientesMDI formularioCliente = (frmClientesMDI)this.MdiParent;
    formularioCliente.dgClientes.Rows.Remove(formularioCliente.dgClientes.CurrentRow);

    ¿Alguien tiene la solución?

    Saludos a todos.
    viernes, 12 de marzo de 2010 1:14

Respuestas

  • hola

    no te recomiendo utilizar esa tecnica, no accedas directo a los controles
    usa propiedades o interfaces para comunciar los formulario de forma desacoplada

    y luego si localmente en cada form opera con el control pero apsa entre almbos informacion standar, por ejemplo el id del cliente, para buscarlo en la grilla y eliminarlos

    si puede ser algo mas tedioso, y con mas codificacion, pero lograras un desacoplamiento completo de los formulario y ademas fomentaras la reutilziacion y un buen diseño


    - lo que no entendi es la comunciacion ya que se mezcla un poco, donde tienes que eliminar es en el form padre o en el hijo?

    porque MdoParent es una propiedad que tiene el form hijo cuando creas la instancia y usas el Show(), si haces this en el frmPrincipal estas referenciadose a si mismo, no al frmCliente

     -demas le pones como nombre frmClienteMDI, pero este no es MDI, el que si lo es porque imagino lo has establecido como MdiContainer=true es frmPrincipal, frmCliente es el form fijo

    en tu caso lo que debes tener es la instancia cuando hiciste el Show() del form hijo

    mira este link

    [WinForms] Instancia Única de Formulario

    como veras alli se hace uso de propiedades para solo tener una instancia del forma, ademas sirve en tu caso para poder acceder al mismo correctamente

    entonces en tu caso en el frmPrincipal podrias tener

    private frmCliente form = null;

    private frmCliente FormInstance
    {
        get
        {
            if (form == null)
            {
                form = new frmCliente();
                form.Disposed += new EventHandler(form_Disposed);
            }

            return form;
        }
    }

    void form_Disposed(object sender, EventArgs e)
    {
        form = null;
    }



    y para usarlo harias

    DialogResult dr = MessageBox.Show(this, "¿Seguro que desea eliminar el cliente?", "Eliminar cliente", MessageBoxButtons.YesNo,
                     MessageBoxIcon.Question);
    if (dr == DialogResult.Yes)
    {
        this.FormInstance.EliminarCliente();
    }


    por supuesto en el frmclietne deberas crear el metodo publico EliminarCliente()
    pero como veras nucna se accede directo al control, simpre es por metodos o propiedades, y que estos si trabajen de forma local con el control


    lo que no entendi es porque tomas el CurrentRow del form de cliente, y lo mandas a eliminar a su misma grilla

    en ese caso podrias ahcer en el frmCliente


    public void EliminarCliente()
    {
         dgClientes.Rows.Remove(dgClientes.CurrentRow);
    }

    como este metodo esta local al frmclietne accede directo al controls, pero por estas publico puedes llamarlo desde el formprincipal, sin pasale paramwetros


    te dejo algunos link adicionales muy utiles en donde explico lo que comente sobre propiedades e interfaces

    C# - Winforms, realizar tareas antes de inicializar aplicacion

    C# Comunicar formularios MDI


    C# DataGridView Parte 3 Pasaje de informaci ó n entre grillas en distintos formularios



    bueno espero sea de utilidad la explicacion

    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    • Marcado como respuesta Spaikers viernes, 12 de marzo de 2010 13:22
    viernes, 12 de marzo de 2010 1:46

Todas las respuestas

  • hola

    no te recomiendo utilizar esa tecnica, no accedas directo a los controles
    usa propiedades o interfaces para comunciar los formulario de forma desacoplada

    y luego si localmente en cada form opera con el control pero apsa entre almbos informacion standar, por ejemplo el id del cliente, para buscarlo en la grilla y eliminarlos

    si puede ser algo mas tedioso, y con mas codificacion, pero lograras un desacoplamiento completo de los formulario y ademas fomentaras la reutilziacion y un buen diseño


    - lo que no entendi es la comunciacion ya que se mezcla un poco, donde tienes que eliminar es en el form padre o en el hijo?

    porque MdoParent es una propiedad que tiene el form hijo cuando creas la instancia y usas el Show(), si haces this en el frmPrincipal estas referenciadose a si mismo, no al frmCliente

     -demas le pones como nombre frmClienteMDI, pero este no es MDI, el que si lo es porque imagino lo has establecido como MdiContainer=true es frmPrincipal, frmCliente es el form fijo

    en tu caso lo que debes tener es la instancia cuando hiciste el Show() del form hijo

    mira este link

    [WinForms] Instancia Única de Formulario

    como veras alli se hace uso de propiedades para solo tener una instancia del forma, ademas sirve en tu caso para poder acceder al mismo correctamente

    entonces en tu caso en el frmPrincipal podrias tener

    private frmCliente form = null;

    private frmCliente FormInstance
    {
        get
        {
            if (form == null)
            {
                form = new frmCliente();
                form.Disposed += new EventHandler(form_Disposed);
            }

            return form;
        }
    }

    void form_Disposed(object sender, EventArgs e)
    {
        form = null;
    }



    y para usarlo harias

    DialogResult dr = MessageBox.Show(this, "¿Seguro que desea eliminar el cliente?", "Eliminar cliente", MessageBoxButtons.YesNo,
                     MessageBoxIcon.Question);
    if (dr == DialogResult.Yes)
    {
        this.FormInstance.EliminarCliente();
    }


    por supuesto en el frmclietne deberas crear el metodo publico EliminarCliente()
    pero como veras nucna se accede directo al control, simpre es por metodos o propiedades, y que estos si trabajen de forma local con el control


    lo que no entendi es porque tomas el CurrentRow del form de cliente, y lo mandas a eliminar a su misma grilla

    en ese caso podrias ahcer en el frmCliente


    public void EliminarCliente()
    {
         dgClientes.Rows.Remove(dgClientes.CurrentRow);
    }

    como este metodo esta local al frmclietne accede directo al controls, pero por estas publico puedes llamarlo desde el formprincipal, sin pasale paramwetros


    te dejo algunos link adicionales muy utiles en donde explico lo que comente sobre propiedades e interfaces

    C# - Winforms, realizar tareas antes de inicializar aplicacion

    C# Comunicar formularios MDI


    C# DataGridView Parte 3 Pasaje de informaci ó n entre grillas en distintos formularios



    bueno espero sea de utilidad la explicacion

    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    • Marcado como respuesta Spaikers viernes, 12 de marzo de 2010 13:22
    viernes, 12 de marzo de 2010 1:46
  • Leandro eres la reost....., siempre tienes respuestas a mis preguntas y encima respondes rápido. Lo hice como me explicas pero en vez de crear el método public en el formulario de clientes, lo que hice fue this.InstanciaClientes.dgClientes.Rows.Remove(InstanciaClientes.dgClientes.CurrentRow); desde el formulario Padre.

    Eres un crack, un fuerte abrazo.
    viernes, 12 de marzo de 2010 13:25
  • Te comento Leandro, partiendo del código que me escribistes, te posteo éste para que comentes la diferencia con el tuyo, todo ello si tienes tiempo.

    Formulario Padre:

            private frmClientes formularioClientes = null;

            private void btClientes_ItemClick(..............)
            {
                if (formularioClientes == null)
                {
                    formularioClientes = new frmClientes();
                    formularioClientes.Disposed += new EventHandler(formularioClientes_Disposed);
                    formularioClientes.MdiParent = this;
                    formularioClientes.WindowState = FormWindowState.Maximized;
                    formularioClientes.Show();
                }
                else
                {
                    formularioClientes.WindowState = FormWindowState.Maximized;
                    formularioClientes.BringToFront();
                }
            }

            private void btEliminarCliente_ItemClick(...............)
            {
                DialogResult dr = MessageBox.Show(this, "¿Seguro que desea eliminar el cliente " +
                    formularioClientes.dgClientes.CurrentRow.Cells["Nombre"].Value.ToString().ToUpper() + "?",
                    "Eliminar cliente", MessageBoxButtons.YesNo,
                     MessageBoxIcon.Question);
                if (dr == DialogResult.Yes)
                {
                    formularioClientes.dgClientes.Rows.Remove(formularioClientes.dgClientes.CurrentRow);
                }
            }

    Formulario Hijo:

           Nada de nada ya que uso directamente formularioClientes.dgClientes.Rows.Remove(formularioClientes.dgClientes.CurrentRow); en vez de crear un método llamado eliminarCliente();



    ¿Qué te parece Leandro?

    Saludos.
    sábado, 13 de marzo de 2010 1:52
  • hola

    si estaria correcta la implementacion que has realizado, por ahi objectaria la linea

    formularioClientes.dgClientes.Rows.Remove(formularioClientes.dgClientes.CurrentRow);

    aqui harias un metodo en el form hijo que realzia esa operacion, algo como habia comentado

    public void EliminarCliente()
    {
         dgClientes.Rows.Remove(dgClientes.CurrentRow);
    }


    entonces desde el forma quedaria

           private void btEliminarCliente_ItemClick(...............)
            {
                DialogResult dr = MessageBox.Show(this, "¿Seguro que desea eliminar el cliente " +
                    formularioClientes.dgClientes.CurrentRow.Cells["Nombre"].Value.ToString().ToUpper() + "?",
                    "Eliminar cliente", MessageBoxButtons.YesNo,
                     MessageBoxIcon.Question);
                if (dr == DialogResult.Yes)
                {
                    formularioClientes.EliminarCliente();
                }
            }


    como veras menos intrusivo al dejar que el propio form acceda a sus controles, solo desde el que lo invoca conoce la funcionaldiad que expone

    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    sábado, 13 de marzo de 2010 2:13