2010-09-16 5 views
7

He creado un indicador de ocupado, básicamente una animación de un logotipo girando. Lo agregué a una ventana de inicio de sesión y vinculé la propiedad Visibilidad a la propiedad BusyIndicatorVisibility de mi viewmodel.¿Cómo puedo forzar la visualización de mi indicador de ocupado? (WPF)

Cuando hago clic en Iniciar sesión, quiero que aparezca la flecha giratoria mientras se produce el inicio de sesión (llama a un servicio web para determinar si las credenciales de inicio de sesión son correctas). Sin embargo, cuando configuro la visibilidad como visible, continúo con el inicio de sesión, la ruleta no aparece hasta que se completa el inicio de sesión. En la codificación antigua de Winforms, habría agregado una Application.DoEvents. ¿Cómo puedo hacer que el spinner aparezca en WPF en una aplicación MVVM?

El código es:

 private bool Login() 
     { 
      BusyIndicatorVisibility = Visibility.Visible; 
      var result = false; 
      var status = GetConnectionGenerator().Connect(_model); 
      if (status == ConnectionStatus.Successful) 
      { 
       result = true; 
      } 
      else if (status == ConnectionStatus.LoginFailure) 
      { 
       ShowError("Login Failed"); 
       Password = ""; 
      } 
      else 
      { 
       ShowError("Unknown User"); 
      } 
      BusyIndicatorVisibility = Visibility.Collapsed; 
      return result; 
     } 
+1

+1 por hacerme estremecer con un DoEvents ;-) – Stimul8d

Respuesta

8

Usted tiene que hacer su entrada asíncrono. Puede usar el BackgroundWorker para hacer esto. Algo así como:

BusyIndicatorVisibility = Visibility.Visible; 
// Disable here also your UI to not allow the user to do things that are not allowed during login-validation 
BackgroundWorker bgWorker = new BackgroundWorker() ; 
bgWorker.DoWork += (s, e) => { 
    e.Result=Login(); // Do the login. As an example, I return the login-validation-result over e.Result. 
}; 
bgWorker.RunWorkerCompleted += (s, e) => { 
    BusyIndicatorVisibility = Visibility.Collapsed; 
    // Enable here the UI 
    // You can get the login-result via the e.Result. Make sure to check also the e.Error for errors that happended during the login-operation 
}; 
bgWorker.RunWorkerAsync(); 

Sólo para completitud: Existe la posibilidad de dar la interfaz de usuario el tiempo para refrescar antes del inicio de sesión se lleva a cabo. Esto se hace a través del despachador. Sin embargo, este es un truco y la IMO nunca debe ser utilizada. Pero si le interesa esto, puede buscar StackOverflow para wpf doevents.

+0

Mierda. Esperaba que esa no fuera la respuesta. He heredado una gran aplicación con cosas de UI sucediendo por todas partes y tengo un día para agregar este indicador ocupado a aproximadamente 50 pantallas. No hay una manera más fácil? – Unhappy

+0

El otro problema es que lo intenté en la pantalla de inicio de sesión y rompe las pruebas :( – Unhappy

+0

Tal vez algo así: En el método de Inicio de sesión(), abra una ventana modal (window.ShowDialog) y haga allí el inicio de sesión. Cierre la ventana después de que se haya completado el inicio de sesión. Por lo tanto, la aplicación está bloqueada hasta que se haya iniciado sesión. La ventana en sí muestra que la aplicación está ocupada. Dentro de la ventana, usaría BackgroundWorker. – HCL

0

¿Su código de inicio de sesión se ejecuta en el hilo de la interfaz de usuario? Eso podría bloquear las actualizaciones de enlace de datos.

+0

Sí, por desgracia. – Unhappy

Cuestiones relacionadas