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

DialogMessage con MVVM

http://mvvmlight.codeplex.com/discussions/267282

In my ViewModel I have this code:

 var message = new DialogMessage("Dit artikel is al verkocht", DialogMessageCallback)
                {
                    Button = MessageBoxButton.OK,
                    Caption = "Continue?"
                };

                Messenger.Default.Send(message);

And in my MainWindow.xaml.cs:

InitializeComponent(); Messenger.Default.Register<DialogMessage>( this, msg => { var result = MessageBox.Show( msg.Content, msg.Caption, msg.Button); // Send callback msg.ProcessCallback(result); });

 

Como veis, no tiene ninguna complicación gracias a Galasoft.

 

Sonrisa

Abrir ClickOnce Application desde el ViewModel

 

Me rindo!

Con lo simple que parece, pero no va! He probado Window.Navigate, PopUpWindow y hasta javascript.

Lo bueno es que en desarrollo funciona correctamente, pero en producción, se abre la ventana que va a lanzar la aplicación, e inesperadamente se cierra y no se lanza el programa.

Solución. Meter un HyperlinkButton en el View y  hacer binding del NavigateUri.

No es lo que quería, pero no he encontrado otro modo. Si alguien lo sabe, que no dude en publicarlo. He perdido muchas horas de prueba y ERROR, y no puedo dedicar más tiempo.

Triste