none
Buscar registros desde otro form ? RRS feed

  • Pregunta

  • Hola a todos, actualmente estoy trabajando en un sistema en C# con conexión con SQL Server, hasta ahora no he tenido ningún problema. Pero hace días que tuve la idea de buscar registros desde otro formulario, me explico mas detalladamente:

    Tengo un formulario al cual llamaremos "Form1", el cual solo tiene un componente, en este caso el "DataGridView",

    por otro lado tengo otro formulario "Form2", el cual es el formulario de busqueda, el cual posee los filtros de buqueda y demás cosas. Lo que necesito es  que cuando yo escriba por ejemplo el nombre de un cliente en el "Form2" para hacer una busqueda, los registros encontrados me aparezcan en el "Form1" específicamente en el datagridview.

     

    Hasta ahora he intentado todo, desde cambiar la propiedad "Modifier" del datagrid para poder trabajar con el segundo formulario (form1.datagridview), y nada, mi problema no es la búsqueda, si no mas bien que el datagridview se valla actualizando desde el otro form. Se los agradecería mucho si pudieran ayudarme. Gracias.

     

    lunes, 26 de septiembre de 2011 14:32

Respuestas

  • hola

    podrias implementar algo como esto

    Filtros Condicionales (1/2)

    solo que lo aplicas desde otro form

     

    cambiar la propiedad "Modifier" del datagrid para poder trabajar con el segundo formulario (form1.datagridview), y nada

    es que aplicas de forma incorrecta la logica, no deberias acceder a los controelsd e forma directa desde otro form

    Comunicar formularios de forma desacoplada

    como veras si el Form1 define una interfaz de comunciacion podrias pasarle por esta el datatable con los datos que debe cargar y que el form2 resolvio

     

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 26 de septiembre de 2011 14:39

Todas las respuestas

  • hola

    podrias implementar algo como esto

    Filtros Condicionales (1/2)

    solo que lo aplicas desde otro form

     

    cambiar la propiedad "Modifier" del datagrid para poder trabajar con el segundo formulario (form1.datagridview), y nada

    es que aplicas de forma incorrecta la logica, no deberias acceder a los controelsd e forma directa desde otro form

    Comunicar formularios de forma desacoplada

    como veras si el Form1 define una interfaz de comunciacion podrias pasarle por esta el datatable con los datos que debe cargar y que el form2 resolvio

     

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 26 de septiembre de 2011 14:39
  • Hola Manuel.

    Se me ocurre algo como esto. 

    1. En el form2 defines una propiead del tipo Action<DataTable>, tal que así.

     

    public Action<DataTable> RetornarDatos { set; private get; }
    


    2. En el boton donde realizas la busqueda en el form2  escribes lo siguiente.

    private void button1_Click(object sender, EventArgs e)
            {
                if (this.RetornarDatos != null)
                {
                    //Esta parte tienes que sustituirla por tu acceso a datos
                    //Lectura de Sql Server, como puedes ver yo genero un datatable
                    //manual
                    DataTable t = new DataTable();
                    t.Columns.Add("Id");
                    t.Columns.Add("Nombre");
                    t.Rows.Add(new object[] { 1, "Manuel Hernandez" });
                    t.Rows.Add(new object[] { 2, "Leandro Tuttini" });
                    t.Rows.Add(new object[] { 3, "Pedro Hurtado" });
                    RetornarDatos(t);
                }
                this.Close();
            }
    


    3. En el form1 defines un metodo privado de tu formulario que es que se encarga de regoger el DataTable y asignarlo al DataGridView.

     private void RefrescarDatos(DataTable t)
            {
                this.dataGridView1.DataSource = t;
            }
    


    4. Para lanzar el formulario tienes que hacer lo siguiente.

    Form2 frm = new Form2();
                frm.RetornarDatos = RefrescarDatos;
                frm.ShowDialog();
                frm.RetornarDatos = null;
    

    Una puntualización, no cambies la propiedad "Modifier" puesto que los controles se crean a nivel de instancia y para que eso te funcione tendrías que pasar todo el Form1 a Form2 o definir el DataGrid de forma estática, cosa que no te aconsejo.

     Es decir aplica esta frase que comento Leandro "es que aplicas de forma incorrecta la logica, no deberias acceder a los controelsd e forma directa desde otro form", pero no cambies la propiedad "Modifier"


    Saludos,


    phurtado
    lunes, 26 de septiembre de 2011 15:09
    Moderador
  • Leandro muchas gracias !! :) 

    Hice lo que indicaste en tu Blog con el uso de la interfaces y funciono perfectamente. Te doy gracias por lo de los filtros, no lo buscaba, pero esta interesante lo que hiciste allí, lo voy a descargar para aprender cosas que quizás desconozco.

    Voy a plantear lo que hice, para aportar algo:

    Formulario #2 (Busqueda)

     

    private void textBox1_TextChanged(object sender, EventArgs e)
            {
    
                 using (SqlConnection sql = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=Clientes;Integrated Security=true"))
                {
               
                    adt = new SqlDataAdapter("Select * from usuarios where Nombre like'" + this.textBox1.Text + "%'", sql); 
    // Se que utilizar la consulta con '" %' no es buena practica, pero solo // lo hago para colocar un código rápido. :)
                    DataTable dt = new DataTable();
                    adt.Fill(dt);
                    datatable iform = this.Owner as datatable;
                     if(iform != null) { iform.dt(dt); }
    
    
                    
              
    
               
            };
            }
    
    
    // Formulario #1
    
    
    
    public void dt(DataTable dt)
            {
    
                this.dataGridView1.DataSource = dt;
    
    
    
            }
    
     private void Form1_Load(object sender, EventArgs e)
            {
                Form2 form = new Form2();
    
                form.Show(this);
    
    
                
                using (SqlConnection sql = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=Clientes;Integrated Security=true"))
                {
                    SqlDataAdapter adt = new SqlDataAdapter("Select * from usuarios", sql);
                    
                    DataTable dt = new DataTable();
                    adt.Fill(dt);
    
                    this.dataGridView1.DataSource = dt; 
                    
    
                    
    
    
    
    
    
                };
    
    
    
                
    
    
    
            }
    
    
    
    // Interface
    
    
    public interface datatable
    
            {
    
    
    
                 void dt(DataTable dt);
    
    
    
    
    
    
    
    
    
            }
    
    
    
    
    
    



    lunes, 26 de septiembre de 2011 15:29
  • Hola,

    Manuel, como veo que lo que haces es estudiar, has optado desde mi punto de vista por un mal ejemplo, puesto que si estás acoplando. Es decir tu cuando haces Form2.Show(this), dependes del formulario de destino para poder funcionar. Si tu ejecutas Form1.Show() eso no te va a retornar datos nunca puesto owner es null. Pero es más si trabajas en vez de con Formularios con Usercontrol esa propiedad no existe.

     

    Está bien que uses una interface, pero no obtenerla a partir de la propiedad Owner de un Windows Form, sino que esa interfaz debe de estar  implementada en el destino no en el origen.

    Siento decir que no me gusta el ejemplo de Leandro de "Comunicar Formularios de Forma Desacoplada".

    Piensa eso.

    Saludos,


    phurtado
    lunes, 26 de septiembre de 2011 15:54
    Moderador
  • el owner es una propiedad comun de todos los formularios, por lo tanto pasas la instancia por esta me parecio lo mas natural

    es logico que sino defines ninguna deberas controlar que al castear a la interfaz esta no se puede lograr por lo tanto no comuncias los formularios

     

    como te he comentado si un ejemplo no gusta, entonces crea un blog propio y ejemplifica como deberia realizarse de la forma correcta

     

    recuerda demas que el es form2(hijo) quien envia la info al form1(padre), y no que el form1(padre) quien toma la info del form2(hijo), por eso es que la accion se realzia desde el form2 y no al contrario

    por supuesto se podria adaptar para que el form2(hijo) exponga la info en una propiedad y mediante algun evento informa al form1(padre) que loa datos estan disponibles

    pero bueno esa no era la finalidad del articulo, la idea er invocar directo y no solo notificar

     

    saludois


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 26 de septiembre de 2011 16:04
  • Hola,

    Manuel, como veo que lo que haces es estudiar, has optado desde mi punto de vista por un mal ejemplo, puesto que si estás acoplando. Es decir tu cuando haces Form2.Show(this), dependes del formulario de destino para poder funcionar. Si tu ejecutas Form1.Show() eso no te va a retornar datos nunca puesto owner es null. Pero es más si trabajas en vez de con Formularios con Usercontrol esa propiedad no existe.

     

    Está bien que uses una interface, pero no obtenerla a partir de la propiedad Owner de un Windows Form, sino que esa interfaz debe de estar  implementada en el destino no en el origen.

    Siento decir que no me gusta el ejemplo de Leandro de "Comunicar Formularios de Forma Desacoplada".

    Piensa eso.

    Saludos,


    phurtado

    Hola Pedro Hurtado, realmente tienes razón en lo que dices. La realidad es que cuando conteste aún no habia visto tu respuesta. Pensare en lo que dices, ya que si es cierto que el "Form2" depende del formulario de destino, por eso su propiedad "Owner". Gracias por la aclaración. Estudiare un poco mas esto.

    Saludos. :)

    lunes, 26 de septiembre de 2011 16:10
  • ya que si es cierto que el "Form2" depende del formulario de destino, por eso su propiedad "Owner"

    el form 2 no depedne del formulario de destino

    depende d ela interfaz, el owner solo se usa como medio para apsar la instancia

    si creas un Form3 que use el form2 puede hacer siempre que este implemente la interfaz

    y si creas un form4 que use el form2 puede hacer siempre que este implemente la interfaz

    o sea se reutilzia y no queda acoplado, porque la interfaz lo facilita

    el owner es solo un medio nada mas, puede si quieres crear una propeidad para apsar la instancia sino quieres el owner es indistinto

    es mas aqui lo aplico

    Comunicar formularios MDI

     

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 26 de septiembre de 2011 16:19
  • ya que si es cierto que el "Form2" depende del formulario de destino, por eso su propiedad "Owner"

    el form 2 no depedne del formulario de destino

    depende d ela interfaz, el owner solo se usa como medio para apsar la instancia

    si creas un Form3 que use el form2 puede hacer siempre que este implemente la interfaz

    y si creas un form4 que use el form2 puede hacer siempre que este implemente la interfaz

    o sea se reutilzia y no queda acoplado, porque la interfaz lo facilita

    el owner es solo un medio nada mas, puede si quieres crear una propeidad para apsar la instancia sino quieres el owner es indistinto

    es mas aqui lo aplico

    Comunicar formularios MDI

     

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    Entiendo, voy a leer el articulo, para dejar atrás un poco la confusión, ya que realmente me confundí un poco :). La realidad es que los dos ejemplos están bien, pero para lo que busco el ejemplo que propusiste me funciono y suple mi necesidad. La realidad nunca había utilizado la propiedad Owner, tendré que leer un poco mas de ella. Gracias.
    lunes, 26 de septiembre de 2011 16:28
  • el owner es una propiedad comun de todos los formularios, por lo tanto pasas la instancia por esta me parecio lo mas natural

    es logico que sino defines ninguna deberas controlar que al castear a la interfaz esta no se puede lograr por lo tanto no comuncias los formularios

     

    como te he comentado si un ejemplo no gusta, entonces crea un blog propio y ejemplifica como deberia realizarse de la forma correcta

     

    recuerda demas que el es form2(hijo) quien envia la info al form1(padre), y no que el form1(padre) quien toma la info del form2(hijo), por eso es que la accion se realzia desde el form2 y no al contrario

    por supuesto se podria adaptar para que el form2(hijo) exponga la info en una propiedad y mediante algun evento informa al form1(padre) que loa datos estan disponibles

    pero bueno esa no era la finalidad del articulo, la idea er invocar directo y no solo notificar

     

    saludois


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    Leandro el Owner es una propiedad común en todos los formularios, pero no en UserControl, por eso mi critica.

    Fijate en esta frase mia.

    "Está bien que uses una interface, pero no obtenerla a partir de la propiedad Owner de un Windows Form, sino que esa interfaz debe de estar  implementada en el destino no en el origen."

    Cuando digo que esa interface debe de estar implementada en el destino no en el origen, es para que Form2 no sepa absolutamente nada de Form1.

    Por eso pase mi código de esa forma basando toda la comunicación en un Action que como tu bien sabes es un Delegate y no necesitas de ningún evento, así es como normalmente lo hago en la vida real.

    Para explicar esto no hace falta hacer un blog, aunque la verdad es que me lo estoy pensando :). Siento si te sento mal, pero no me gusta tu ejemplo.

     

    Mira el siguiente ejemplo, que también puedes criticar :)

    1. Definición de la interface.

     

    public interface IReturnValue
        {
            Delegate ReturnValues { get; set; }
        }
    

     


    2. Implementación en el Destino.

     

     #region Miembros de IReturnValue
    
            Delegate IReturnValue.ReturnValues { get; set; }
           
    
            #endregion
    

     


    Si te fijas está implementada de forma explicita.

    3. Cuando aplico el filtro y obtengo el DataTable lo devuelvo así.

     

     private void button1_Click(object sender, EventArgs e)
            {
                IReturnValue returnValues = this;
                if (returnValues.ReturnValues != null)
                {
                    DataTable t = new DataTable();
                    t.Columns.Add("Id", typeof(int));
                    t.Columns.Add("Descripcion", typeof(string));
                    t.Rows.Add(new object[] { 1, "Manuel Hernandez" });
                    t.Rows.Add(new object[] { 2, "Leandro Tuttini" });
                    t.Rows.Add(new object[] { 3, "Pedro Hurtado" });
                    returnValues.ReturnValues.DynamicInvoke(t);
                }
                this.Close();
            }
    
    4. Para llamar al filtro hago lo siguiente.

     

     

     private void button1_Click(object sender, EventArgs e)
            {
                this.LanzarFiltro();
            }
            private void LanzarFiltro()
            {
                Form2 frm = new Form2();
                IReturnValue returnValues = frm;
                returnValues.ReturnValues = new Action<DataTable>((table) => { this.dataGridView1.DataSource = table; });
                frm.ShowDialog();
                returnValues.ReturnValues = null;
            }
    

     

     Como puedes ver la Interface la implemento en el destino y es este el que devuelve los datos al origen en este linea.

    new Action<DataTable>((table) => { this.dataGridView1.DataSource = table; });

    Ahora lo tuyo es valido, si, pero solo para System.Windows.Forms.Form pero no para System.Windows.Form.UserControl

    Saludos.


    phurtado
    lunes, 26 de septiembre de 2011 17:19
    Moderador
  • el Owner es una propiedad común en todos los formularios, pero no en UserControl, por eso mi critica.

    y quien menciono un user control aqui, estamos hablando de comunciar formularios

    esto lo has inventado, estas creando requerimientos que nunca se plantearon

    es logico que si me cambias la base de la pregunta te cambiare la repsuesta que apliques

     

    es para que Form2 no sepa absolutamente nada de Form1.

    y no sabe nada de form1, porque lo unico que le interesa es la interfaz, si se manda un owner como instancia invocar ale metodo de la interfaz sino se lo asigna no invocara anda

    ojo esta es solo una tecnica es mas que sabido que tambien se podria lograr con evento

    pero ese no era el objetivo del articulo


    Como puedes ver la Interface la implemento en el destino y es este el que devuelve los datos al origen en este linea.

    si bueno es otra tecnica

    tambien se podria aplciar eventos, como ser suar un ShowDialog y controlar el Closing del form2

    exponiendo la info en una propiedad del form2 para que en el evnetro tomarla de alli

    esa sis eria la ams simple de todas

    como se plantea aqui

    http://social.msdn.microsoft.com/Forums/es/vbes/thread/508c6966-7a76-4415-810d-74c6af86134a

     

    Ahora lo tuyo es valido, si, pero solo para System.Windows.Forms.Form pero no para System.Windows.Form.UserControl

    claro la idea lo dice el titulo del articulo comunicar "formulario", no controles

     

    new Action<DataTable>((table) => { this.dataGridView1.DataSource = table; });

    no veo en ningun lado que consultaran que version de .net esta usando quien hace la pregunta

    ten en cuenta que muchos aun usan la verion 1.1, digo haces implemenmtacion simples con el Action pero apsalas a delegados y explicalos a quien pregunta veras que no es tan simpel somo usar una interfaz, se explcia mas simple el uso de contratod de como funciona los delegados


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 26 de septiembre de 2011 17:42
  • Hola Leandro,

    esto lo has inventado, estas creando requerimientos que nunca se plantearon.

    Yo no he inventado nada, lo único que he dicho es Owner es una propiead especifica de System.Windows.Forms.Form, con lo cual si mañana en su proyecto necesita comunicar un Formulario con un UserControl esa técnica no va a funcionar, por eso he advertido, porque no has utilizado la propiedad Tag?

    y no sabe nada de form1, porque lo unico que le interesa es la interfaz, si se manda un owner como instancia invocar ale metodo de la interfaz sino se lo asigna no invocara anda

    Que no sabe, imagina que Manuel hace lo siguiente.

    From1 frm = this.Owner as Form1

    if (frm!null)

    frm.Controls.Clear();

    Dime si sabe.

    claro la idea lo dice el titulo del articulo comunicar "formulario", no controles

    Estarás de acuerdo que con esa técnica no se puede comunicar un Form con un UserControl, y puede ser que mañana lo necesite.

    ten en cuenta que muchos aun usan la verion 1.1.

    La verdad que veo pocos en 1.1, pero aún así con Delegados se podría hacer. Yo también he implementado un contrato(Interface) y es lo que he dicho desde mi primera respuesta.

    Saludos,


    phurtado
    lunes, 26 de septiembre de 2011 17:58
    Moderador
  • porque no has utilizado la propiedad Tag?

    simplemente porque es una de tantas variantes, y forma de lograrlo, esta es solo una de ellas pero como todo no es la unica forma

    ademas del tag al owner estaria mas o menos en lo mismo, se busque un medio u otro la idea es pasar la instalacia, delegado o lo que se necesite

    es mas el owner tambien se puede definri como propiedad


    Que no sabe, imagina que Manuel hace lo siguiente. From1 frm = this.Owner as Form1

    pero eso no deberia hacerlo, si lo hiciera es que no ha entendido el articulo

    y logico la implementacion quedaria incorrecta


    puede ser que mañana lo necesite.

    si tengo que responder pensando en el mañana de todas las preguntas que contesto, bueno me tardaria varios dias contestando una sola pregunta



    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 26 de septiembre de 2011 18:17
  • Hola Leandro,

    Veo que cada vez queda menos que debatir y no discutir :)

    ademas del tag al owner estaria mas o menos en lo mismo, se busque un medio u otro la idea es pasar la instalacia, delegado o lo que se necesite.

    Pues no, puesto que con el Owner puede eliminar o alterar los controles del destino mientras que con el Tag eso es imposible.

    es mas el owner tambien se puede definri como propiedad

    No se si te has confundido, pero para definirla tendrías que utilizar "new" y creo que eso no es el caso. Es más Owner esta definido de la siguiente forma.

    public Form Owner { get; set; }

    Con lo cual veo que es del tipo Form es decir que pasas siempre el formulario propietario.

    Cuando digo "new", se puede hacer esto public new int Owner { get; set; } , pero eso redefine la propiedad "Owner" de la instancia no de la base, es decir base.Owner devuelve un objeto del tipo Form al cual puedo seguir eliminado o alterando los controles.

    pero eso no deberia hacerlo, si lo hiciera es que no ha entendido el articulo

    Ahora si sabe que es el Owner.

    si tengo que responder pensando en el mañana de todas las preguntas que contesto, bueno me tardaria varios dias contestando una sola pregunta.

    Eso es criterio del que responde, yo lo único que he hecho es comentar una cosa que no me gusta :).

     

    Saludos,


    phurtado
    lunes, 26 de septiembre de 2011 20:18
    Moderador
  • Pues no, puesto que con el Owner puede eliminar o alterar los controles del destino mientras que con el Tag eso es imposible.

    no entendi, si haces

    Form1 frm1 = this.Tag as Form1;

    tambeine stas accediendo al form que pasaste y peude modifcar o acceder a los controles de este

    igual que lo haces con el Owner

    Con lo cual veo que es del tipo Form es decir que pasas siempre el formulario propietario.

    claro es un form, peor no entendi lo del new que planteas

    si haces desde el form1

    Form2 frm2 = new Form2();

    frm2.Owner = this; //este seria el form1

    frm2.Show();

    es lo mismo el owner que el Tag, o algo no estoy viendo

    Ahora si sabe que es el Owner.

    se supone que el es quien lo esta desarrollando, sino sabe que sua el owner como medio para apsar un valor bueno ahi ya no hay nada mas que hacer

    es lo mismo que tu ejemplo con delegados sino sabe que tiene que asignar el "ReturnValues", estamos en los mismo

     

    Eso es criterio del que responde, yo lo único que he hecho es comentar una cosa que no me gusta

    me parece perfecto, asi como a mi me gusta llevar la contra, jeje, si nadie lleva la contra no se armarina debates y no se aprenderia


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 26 de septiembre de 2011 20:33
  • Hola,

     

    Form1 frm1 = this.Tag as Form1;

    tambeine stas accediendo al form que pasaste y peude modifcar o acceder a los controles de este

    igual que lo haces con el Owner

    Efectivamente tu lo has dicho y es donde yo quería llegar. Siempre se puede recuperar la instancia del origen excepto que hagas lo siguiente.

    public Action<DataTable> RetornarDatos { set; private get; }

    Es decir si tu lo pasas por el Tag,Owner o implementas la interface IForm  en Form1 y creas esta propieadd en el destino.

     

    public IForm Origen { get; set; }

    Siempre vas a poder hacer esto y la variable frm es el Form1, con lo cual puedes alterar controles y mas cosas como llamar a métodos privados por reflection.

    Form1 frm = this.Owner as Form1.

    Form1 frm = this.Tag as Form1.

    Form1 frm = this.Origen as Form1.

    Es más con todas recuperas la instancia incluso con mi segundo ejemplo.

    Si tu haces lo siguiente es que ni compila.

     Form1 frm = this.RetornarDatos as Form1;

     

    No se puede convertir el tipo 'System.Action<System.Data.DataTable>' en 'WindowsFormsApplication21.Form1' mediante una conversión de referencia, boxing, unboxing, de ajuste del texto o de tipo null.

     

    y si haces esto

    Form1 frm = (Form1)this.RetornarDatos;

    No se puede convertir el tipo 'System.Action<System.Data.DataTable>' en 'WindowsFormsApplication21.Form1

    Con lo cual Leandro estaremos de acuerdo que una buena técnica para pasar datos entre Formularios y que el destino no pueda acceder al origen, puede ser mediante Delegados :)


    claro es un form, peor no entendi lo del new que planteas 

    Entendí con esta frase tuya "es mas el owner tambien se puede definri como propiedad" que pensabas en redefinir la propieadad Owner no asignarla como has explicado en tu última respuesta.

     


    Saludos.

     


     



    phurtado
    lunes, 26 de septiembre de 2011 21:21
    Moderador