none
Pasar parámetros a una ventana inactiva de WPF, C Sharp y EF RRS feed

  • Pregunta

  • Buenas tardes, tengo una ventana de WPF que tiene unos combobox y unos  texbox la idea es abrir otra ventana que tiene un datagrid ahy selecciono el registro y ese registro que seleccione debe cerrar la ventana activa en ese momento y pasar los parámetros a la ventana de donde se invoco para llenar el combobox y el texbox con esos parámetros.

    Uso el evento MouseDoubleClick y cierro ese formulario pero no se como hacer que el combobox y el textbox se establezcan los valores que seleccione en el datagrid de la otra ventana.

    El combobox lo lleno así:

    //Primero la clase
    
    public class clin_art
        {
            public string co_lin { get; set; }
            public string lin_des { get; set; }
        }
    
    //Luego el el Window_Loaded
    
    var linea = (from lin in inv.lin_art //Carga el ComboBox de las Lineas
                             select new clin_art { co_lin = lin.co_lin, lin_des = lin.lin_des }).ToList();
                cmb_lin.ItemsSource = linea;
    
    //Este es el botón que abre el otro formulario
    
    private void button4_Click(object sender, RoutedEventArgs e)
            {            
                busqueda bus = new busqueda();
                bus.label1.Content = "Linea";
                bus.Show();
                Window_Loaded(null, null);
            }
     

    Y el el otro formulario que abro tengo este código

    // Lo lleno asi
    
    List<busca> bu = (from x in inv.lin_art                                      
                                          where textBox1.Text == "" ? x.lin_des != "XXXX" : x.lin_des.Contains(textBox1.Text)
                                         select new busca { codigo = x.co_lin, descrip = x.lin_des }).ToList();
                        dg_busq.ItemsSource = bu;
    
    //Y para seleccionar el registro:
    
    private void dg_busq_MouseDoubleClick(object sender, MouseButtonEventArgs e)
            {
                if (dg_busq.SelectedIndex == -1)
                {
                    MessageBox.Show("Debe seleccionar un registro");
                }
                else         
                {
                    busca bg = dg_busq.SelectedItem as busca;
                    MainWindow mw = new MainWindow();
                    mw.cmb_lin.Text = bg.codigo;
                    mw.txt_lin.text = bg.descrip;
                    this.Close();                
                }
            }

    Gracias de antemano, espero contar con ustedes.

     

    C. Zapata



    • Editado CAZA - lunes, 30 de abril de 2012 21:42
    lunes, 30 de abril de 2012 21:27

Respuestas

  • Hola CAZA.

    Lo ideal es que hubieses usado mvvm para implementar el proyecto que es la mejor forma de trabajar en WPF, pero como lo tienes implementado con eventos, la forma mas facil de hacer lo que buscas es usando una propiedad publica en la ventana hija que contenga la ventana padre, de modo que la ventana padre establezca esta propiedad para poder ser referenciada.

    En tu ejemplo vuelves a crear una ventana principal con la linea 'MainWindow mw = new MainWindow();' de modo que no es valido al no ser la ventana padre usada actualmente.

    Tienes 2 opciones faciles segun lo que ya tienes implementado:

    1.- si MainWindow es la ventana primaria de la aplicacion, se puede obtener su referencia y establecer el valor con algo asi:

    ((MainWindow)App.Current.MainWindow).cmb_lin.Text = bg.codigo;

    Pero esto solo es si es la ventana principal de la aplicacion.

    2.- establecer una propiedad en la clase hija para guardar la ventana padre:

    public Window Owner { get; set; }

    De modo que al crear la ventana hija sea el la ventana dueña la que la establezca:

                busqueda bus = new busqueda();
                bus.Owner = this;

    De modo que desde la ventana hija ya tienes una referencia a la ventana dueña y la puedes usar (haciendo el cast que corresponda):

    ((MainWindow)this.Owner).cmb_lin.Text = bg.codigo;

    Como se puede observar la segunda opcion es mas flexible que la primera ya que permite que varias ventanas padre usen la ventana hija implementando un cast correcto, lo ideal es hacer uso de algun tipo de interface para ofrecer mayor flexibilidad, pero te he dejado lo mas basico para lo que tienes implementado.

    Si tienes algun problema comentalo.


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    • Propuesto como respuesta Miguel A. González martes, 1 de mayo de 2012 20:43
    • Marcado como respuesta CAZA - jueves, 3 de mayo de 2012 14:13
    martes, 1 de mayo de 2012 9:15

Todas las respuestas

  • Hola CAZA.

    Lo ideal es que hubieses usado mvvm para implementar el proyecto que es la mejor forma de trabajar en WPF, pero como lo tienes implementado con eventos, la forma mas facil de hacer lo que buscas es usando una propiedad publica en la ventana hija que contenga la ventana padre, de modo que la ventana padre establezca esta propiedad para poder ser referenciada.

    En tu ejemplo vuelves a crear una ventana principal con la linea 'MainWindow mw = new MainWindow();' de modo que no es valido al no ser la ventana padre usada actualmente.

    Tienes 2 opciones faciles segun lo que ya tienes implementado:

    1.- si MainWindow es la ventana primaria de la aplicacion, se puede obtener su referencia y establecer el valor con algo asi:

    ((MainWindow)App.Current.MainWindow).cmb_lin.Text = bg.codigo;

    Pero esto solo es si es la ventana principal de la aplicacion.

    2.- establecer una propiedad en la clase hija para guardar la ventana padre:

    public Window Owner { get; set; }

    De modo que al crear la ventana hija sea el la ventana dueña la que la establezca:

                busqueda bus = new busqueda();
                bus.Owner = this;

    De modo que desde la ventana hija ya tienes una referencia a la ventana dueña y la puedes usar (haciendo el cast que corresponda):

    ((MainWindow)this.Owner).cmb_lin.Text = bg.codigo;

    Como se puede observar la segunda opcion es mas flexible que la primera ya que permite que varias ventanas padre usen la ventana hija implementando un cast correcto, lo ideal es hacer uso de algun tipo de interface para ofrecer mayor flexibilidad, pero te he dejado lo mas basico para lo que tienes implementado.

    Si tienes algun problema comentalo.


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    • Propuesto como respuesta Miguel A. González martes, 1 de mayo de 2012 20:43
    • Marcado como respuesta CAZA - jueves, 3 de mayo de 2012 14:13
    martes, 1 de mayo de 2012 9:15
  • David muchísimas gracias por responderme, voy a probar ahorita esto y te comento como me fue


    C. Zapata

    miércoles, 2 de mayo de 2012 20:22
  • David, excelente me funciona bien use la primera opción aunque voy a tratar de probar también la segunda me parece mas flexible como dices tu.

    Ahora bien tengo una duda relacionada con esto y es que el combobox no me lo llena, no se por que por que el ItemsSource me lo muestra sin problemas, puedes ayudarme con esto, se que es sencillo. Gracias


    C. Zapata

    miércoles, 2 de mayo de 2012 20:42
  • David lo que pasa es que para llenar el combobox cmb_lin uso un DataTemplate algo como esto:

    <ComboBox Height="23" HorizontalAlignment="Left" Margin="114,76,0,0" Name="cmb_lin" VerticalAlignment="Top" Width="120" Grid.Row="1" SelectionChanged="cmb_lin_SelectionChanged">
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding Path=co_lin}" Width="100" />
                            <TextBlock Text="{Binding Path=lin_des}" Width="200" />
                        </StackPanel>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>

    Y lo lleno con una consulta que tiene dos valores asi:

    var linea = (from lin in inv.lin_art //Carga el ComboBox de las Lineas
                             select new clin_art { co_lin = lin.co_lin.Trim(), lin_des = lin.lin_des.Trim() }).ToList();
                cmb_lin.ItemsSource = linea;
    Entonce claro le estoy asignando solo el código. No se como le puedo asociar el registro completo como esta en el ItemsSource??



    C. Zapata

    miércoles, 2 de mayo de 2012 21:13
  • Hola CAZA.

    No entiendo muy bien que es lo que ocurre.

    ¿el combo se llena? ¿que es lo que no funciona?.

    En un principio la consulta esta bien, aunque no hace falta que pongas un 'ToList()' al final, ya que todas las consultas linq retornan IEnumerables<T> que es lo necesario para el ItemSource (puedes quitarlo y funcionaria igual).


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    viernes, 4 de mayo de 2012 17:44
  • Gracias David nuevamente por tu respuesta creo que no me expliqué bien.

    Lo que me indicaste me funciono bien, pero mi problema es que tengo el siguiente escenario:

    un combobox y un textbox, la idea es que el usuario seleccione en el combobox el registro el cual muestra dos cosas el código y la descripción de cada registro. Por ejemplo

    01  Juan

    02  Pedro

    03  Angel

    si selecciono 01 el combobox toma el valor de 01 y el textbox que esta al lado toma el valor de Juan. Esto funciona bien, ahora me encontré con el problema de que en ocasiones pueden ser muchos registros y necesitaba algo que me simplificara esto (la búsqueda de registros) por lo que decidí agregar al lado del textbox un botón para buscar registros, la idea es que esto abra otra ventana que tiene un textbox donde escribo cualquier cosa y esto activa yn select con un like de EF para ubicar en un datagrid lo que coincida con lo que se escribió en el, luego se debe hacer dobleclick sobre el registro que quiero en el datagrid y esto cierra esta ventana y llena tanto el combobox como el textbox (aqui fue donde ya me ayudaste) ahora bien resulta que cuando aplico esto me llena perfectamente el textbox pero el combobox permanece en blanco, claro cuando selecciono el registro intento decirle la ventana que llene el combobox solo con el codigo pero el ItemsSource de el usa un datatemplate por que muestro código + descripción.

    Volviendo al ejemplo si el ItemsSource tiene lo siguiente:

    01  Juan

    02  Pedro

    03  Angel

    Pienso que no puedo decirle Combobox1.Text = "01" por ejemplo y no se como decirle Combobox1.Text = "01  Juan".

    Supongo que este es mi problema, no se si me explico bien. Gracias de antemano.


    C. Zapata

    sábado, 5 de mayo de 2012 2:17
  • Hola CAZA.

    Respondo en el hilo que has abierto dedicado al tema, para no dispersar las soluciones:

    http://social.msdn.microsoft.com/Forums/es-ES/wpfes/thread/35ac3768-71d2-455e-8e59-ec55c0ae88d7


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    domingo, 6 de mayo de 2012 11:32
  • Hola Buen Día tengo un problema, yo estoy realizando mi proyecto con MVVM  pero tengo dos ventanas una ventana donde mostrara un DataGrid  con los datos y entonces el usuario seleccionara un elemento de ese dataGrid y le dara clic en un boton cuando suceda esto generara una segunda ventana con los datos de ese elemento.

    Lo que no puedo hacer es como Pasar el id De ese elemento para poder llenar un datagrid de la segunda ventana, sin romper el patron de diseño de antemano muchas gracias.

    Si me puede ayudar te lo agradecería.

    domingo, 30 de septiembre de 2012 14:44
  • Hola HackRock.

    Bueno, todo depende de como tengas el ViewModel.

    En un principio, supongo que tendras una propiedad con la coleccion que rellenara el grid mediante un binding y te hara falta ademas una propiedad con el item seleccionado, el cual puede ser un entero con el id o un indice o el item entero (como tu veas).

    Si tienes estas 2 cosas, ya solo te falta hacer que el ViewModel sea compartido, es muy posible que cada ventana tenga una instancia del viewmodel, pero en general, un viewmodel deberia de ser dispuesto mediante una unica instancia, para esto puedes implementar un singleton, una arquitectura basada en factoria, servicio, IOC, etc. que te permita aceder a una instancia compartida. Para esto ultimo, Yeray escribio un articulo que aunque es para WinRT, te servira como base para tener una idea de lo que digo y poder hacer uso de la implementacion que mas te guste.

    Si tienes problemas con ello, comentalo.


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    lunes, 1 de octubre de 2012 9:30