Reputation: 131
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;
}
Upvotes: 8
Views: 10058
Reputation: 39453
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.
Upvotes: 1
Reputation: 36785
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.
Upvotes: 8
Reputation: 39630
Does your login code run on the UI thread? That might block databinding updates.
Upvotes: 0