开发者

How can I force my busy indicator to display? (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 BusyIndicatorVisibil开发者_运维问答ity 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;
        }


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.


You can try to run busy indicar in a separate thread as this article explains: Creating a Busy Indicator in a separate thread in WPF

Or try running the new BusyIndicator from the Extended WPF Toolkit

But I'm pretty sure that you will be out of luck if you don't place the logic in the background thread.


Does your login code run on the UI thread? That might block databinding updates.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜