Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I force my busy indicator to display? (WPF)

Tags:

mvvm

wpf

I've created a busy indicator - basically an animation of a logo spinning. I've added it to a login window and bound the Visibility property to my viewmodel's BusyIndicatorVisibility property.

When I click login, I want the spinner to appear whilst the login happens (it calls a web service to determine whether the login credentials are correct). However, when I set the visibility to visible, then continue with the login, the spinner doesn't appear until the login is complete. In Winforms old fashioned coding I would have added an Application.DoEvents. How can I make the spinner appear in WPF in an MVVM application?

The code is:

        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;
        }
like image 499
Unhappy Avatar asked Sep 16 '10 09:09

Unhappy


1 Answers

You have to make your login async. You can use the BackgroundWorker to do this. Something like:

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();

Only for completness: There is the possibility to give the UI the time to refresh before the login takes place. This is done over the dispatcher. However this is a hack and IMO never should be used. But if you're interested in this, you can search StackOverflow for wpf doevents.

like image 59
HCL Avatar answered Sep 22 '22 17:09

HCL