none
BackgroundWorker para abrir una nueva ventana tras un proceso largo RRS feed

  • Pregunta

  • Hola

    Estoy usando el objeto backgroundworker (bgw) para que desde una Window1 al dar a un botón se ejecuta en segundo plano un proceso largo en el que se obtiene una lista de elementos que me sirven para rellenar un datagrid en otra ventana Window2 que se debe abrir al terminar el proceso en segundo plano.

    Pero si en el bgw_RunWorkerCompleted(), es decir en el hilo de la Window1 adjunto el DataContext a la Windows2 y la muestro

    Window2 vista = new Window2 { DataContext = vmCuadrante };

    Window2.Show();

    me sale un error de DependencyObject y no se que gaitas más.

    Sin embargo si en ese mismo evento del hilo de la Window1 muestro la Window2 sin el DataContext si que funciona

    Alguna idea?

    Un saludo


    kintela @esekintela

    jueves, 11 de septiembre de 2014 13:41

Todas las respuestas

  • Buenas,

    podrías especificar más el error, así es un poco complicado...

    Gracias!

    jueves, 11 de septiembre de 2014 14:20
  • Hola Lo siento el error concretamente es el que adjunto

    Un saludo y muchas Gracias


    kintela @esekintela

    jueves, 11 de septiembre de 2014 14:22
  • Buenas,

    Prueba a poner esto antes de crear la ventana:

    Application.Current.Dispatcher.Invoke((Action)(delegate
    {
        //Tu código aquí
    }
    Espero que te sirva!

    jueves, 11 de septiembre de 2014 14:28
  • Hola

    Yo en el evento de vuelta del bgw_DoWork() tengo esto

            private void bgw_Ver_Cuadrante_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                if (e.Cancelled)
                {
                    MessageBox.Show("Operación cancelada");
                }
                else if (e.Error != null)
                {
                    MessageBox.Show(e.Error.Message, "Ha ocurrido un error");
                }
                else
                {
                    try
                    {
                        ListaCuadrantes = (List<Cuadrante>)e.Result;

                        CuadranteViewModel vmCuadrante = new CuadranteViewModel();

                        vmCuadrante.Modelo = ListaCuadrantes;
                        vmCuadrante.TipoUsuario = "Coordinador";
                        vmCuadrante.NombreCompleto = NombreCompleto;
                        vmCuadrante.Mes = Mes;
                        vmCuadrante.Año = Año;
                        vmCuadrante.CodigoCoordinador = CodigoCoordinador;

                        //Rellenar Combos Filtros
                        vmCuadrante.Provincias = util.DameCodigoYNombreProvincias();
                        vmCuadrante.Cadenas = util.DameCodigoYNombreCadenas();
                        vmCuadrante.Centros = util.DameCodigoYNombreCentros();
                        vmCuadrante.Promotores = util.DameCodigoYNombrePromotores();

                        this.IsEnabled = true;
                        sp_pie.Visibility = Visibility.Hidden;
                        this.Cursor = Cursors.Arrow;

                        CuadranteWindow vista = new CuadranteWindow(Año, Mes) { DataContext = vmCuadrante };
                        vista.Show();
                    }
                    catch (Exception ex)
                    {                    
                        throw ex;
                    }
                }
            }

    y según me dices tengo que meter todo lo anterior a la creación de la ventana en el Invoke ???

    Un saludo


    kintela @esekintela

    jueves, 11 de septiembre de 2014 14:33
  •    private void bgw_Ver_Cuadrante_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                if (e.Cancelled)
                {
                    MessageBox.Show("Operación cancelada");
                }
                else if (e.Error != null)
                {
                    MessageBox.Show(e.Error.Message, "Ha ocurrido un error");
                }
                else
                {
                    try
                    {
    
    Application.Current.Dispatcher.Invoke((Action)(delegate
    {
      
                        ListaCuadrantes = (List<Cuadrante>)e.Result;
    
                        CuadranteViewModel vmCuadrante = new CuadranteViewModel();
    
                        vmCuadrante.Modelo = ListaCuadrantes;
                        vmCuadrante.TipoUsuario = "Coordinador";
                        vmCuadrante.NombreCompleto = NombreCompleto;
                        vmCuadrante.Mes = Mes;
                        vmCuadrante.Año = Año;
                        vmCuadrante.CodigoCoordinador = CodigoCoordinador;
    
                        //Rellenar Combos Filtros
                        vmCuadrante.Provincias = util.DameCodigoYNombreProvincias();
                        vmCuadrante.Cadenas = util.DameCodigoYNombreCadenas();
                        vmCuadrante.Centros = util.DameCodigoYNombreCentros();
                        vmCuadrante.Promotores = util.DameCodigoYNombrePromotores();
    
                        this.IsEnabled = true;
                        sp_pie.Visibility = Visibility.Hidden;
                        this.Cursor = Cursors.Arrow;
    
                        CuadranteWindow vista = new CuadranteWindow(Año, Mes) { DataContext = vmCuadrante };
                        vista.Show();
       
    }
    
                 }
                    catch (Exception ex)
                    {                    
                        throw ex;
                    }
                }
            }

    Disculpa las indentaciones, que he hecho copy-paste

    jueves, 11 de septiembre de 2014 14:53
  • Muchas Gracias pero me sigue dando el mismo error.

    La verdad es que todo este lío solo lo estoy necesitando para poder mostrar un progress bar mientras se recuperan los datos de la segunda ventana ya que mientras se obtienen no dejo hacer nada más, pero me está resultando desalentador vamos.

    Un saludo


    kintela @esekintela

    jueves, 11 de septiembre de 2014 15:00
  • Si quieres mostrar una progress bar echa un ojo a este enlace:

    http://www.codeproject.com/Tips/83317/BackgroundWorker-and-ProgressBar-demo

    Saludos!

    jueves, 11 de septiembre de 2014 15:09
  • Hola

    Quiero mostrar un progressbar mientras se ejecuta un proceso de larga duración que lanzo en una ventana y que al terminar se muestra el resultado en otra. Vamos algo totalmente lógico y normal y resulta que con WPF se convierte en un infierno ya que si no usar hilos distintos no funciona por que cuando muestras la progressbar y empieza el proceso en el mismo hilo la barra se bloquea y no sirve para nada y si usas otro hilo al mostrar la otra ventana el error del dispatcher. Un cristo vamos

    Estoy desesperado con este tema

    Un saludo


    kintela @esekintela

    martes, 16 de septiembre de 2014 15:38
  • Buenas,

    Todo lo que sea comunicar ventanas entre sí en WPF es un infierno... Para ello, está el patrón composite, en particular utilizar WPF MVVM con PRISM. Montar la arquitectura es bastante complejo, pero a cambio, podrás comunicar ventanas, mostrar progress bar y desacoplar hilos de una manera sencilla, ya que prism provee al desarrollador de eventos y herramientas para tal fin.

    Te paso unos enlaces:

    http://msdn.microsoft.com/es-es/library/gg406140.aspx

    http://msdn.microsoft.com/en-us/library/ff648465.aspx

    https://www.youtube.com/watch?v=KTtTW-BmXJg

    http://www.c-sharpcorner.com/uploadfile/sanks/introduction-to-prism-composite-application-library-cal-for-wpf-and-silverlight/

    Espero que esto te oriente, porque efectivamente con WPF MVVM, es bastante complejo.

    Saludos! 

    viernes, 19 de septiembre de 2014 19:26
  • Muchas Gracias Ismael. Les echaré un vistazo

    kintela @esekintela

    lunes, 22 de septiembre de 2014 10:25