Refrescar IsBusy de la View mientras cargo un proyecto WF en el ViewModel

 

Me he encontrado con este problema, y tras pegarme con Threads,  BackgroundWorker, Task, Dispatcher, DispatcherPriority, delegados y hasta SynchronizationContext, al final la solución ha sido:

En el View:

public MainWindow()
       {
         
           InitializeComponent();

Messenger.Default.Register<MyMessenger<Busy>>(this, (p) =>
{

// p.Content.Wait es bool
               BusyOn(p.Content.Wait);

});

         

====================

private void BusyOn(bool b)
       {
           Dispatcher.Invoke(DispatcherPriority.Send, (ThreadStart)delegate
           {
              _busy.IsBusy = b;

              _busy.MyRefresh();
              
           });

//NO FUNCIONA   

//_context = SynchronizationContext.Current;
           //if (_context == null)
           //{
           //    _context = new SynchronizationContext();
           //}

       //    _context.Send(new SendOrPostCallback((s) =>
           //        {
           //            _busy.IsBusy = b;
           //            _busy.MyRefresh();
           //        }

           //), null);

 

//NO FUNCIONA

//_busy.Dispatcher.BeginInvoke((Action)(() =>
//{
// _busy.IsBusy = b;

// _busy.MyRefresh();

//}), DispatcherPriority.Send );

       }

==================

public static class DelegateExtensionMethods
    {

        private static Action EmptyDelegate = delegate() { };

 

        public static void MyRefresh(this UIElement uiElement)
        {

            uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);

        }

    }

==============

en el ViewModel:

private void SetBusy(bool b)//object sender, DoWorkEventArgs e)
      {
          var v = new Busy {  Wait =b};
          Messenger.Default.Send(new MyMessenger<Busy >(v));
      }

private void OpenVista()
        {
          
                          
                        var f = new frm ();
                        f.Loading += new frm.LoadHandler(this.SetBusy);
                         f.Show();

             }

======

en el form WF

// add a delegate
       public delegate void LoadHandler(bool loading);

       // add an event of the delegate type
       public event LoadHandler Loading;

 

private void frm_Load(object sender, EventArgs e)
       {
           //indico q empiezo a cargar
           Loading(true);

          //aquí cargo todo

         
           //indico q he terminado de cargar
           Loading(false);
       }

====

un poco rollo, pero el problema es que el Load del WF me congela el shell de WPF y a pesar de enviar mensajes a la vista, no actualiza los elementos de ésta.

Como veréis utilizo Galasoft para enviar mensajes entre View y ViewModel.

Pero al final, prueba superada.

Sonrisa

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s