如何强制显示忙碌指示器? (WPF)

时间:2020-12-17 21:24:09

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.

我创建了一个忙碌的指标 - 基本上是徽标旋转的动画。我已将其添加到登录窗口并将Visibility属性绑定到我的viewmodel的BusyIndi​​catorVisibility属性。

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?

当我单击登录时,我希望在登录发生时显示微调器(它调用Web服务来确定登录凭据是否正确)。但是,当我将可见性设置为可见时,然后继续登录,则在登录完成之前不会显示微调器。在Winforms旧式编码中,我会添加一个Application.DoEvents。如何让微调器出现在MVVM应用程序的WPF中?

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;
        }

3 个解决方案

#1


8  

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

您必须使您的登录异步。您可以使用BackgroundWorker执行此操作。就像是:

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 * for wpf doevents.

仅用于完整性:在登录发生之前,可以为UI提供刷新的时间。这是通过调度员完成的。然而,这是一个黑客攻击,IMO永远不应该被使用。但是如果您对此感兴趣,可以在*中搜索wpf doevents。

#2


2  

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

您可以尝试在单独的线程中运行busy indicar,如本文所述:在WPF中的单独线程中创建忙指示符

Or try running the new BusyIndicator from the Extended WPF Toolkit

或者尝试从Extended WPF Toolkit运行新的BusyIndi​​cator

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

但是我很确定如果你不将逻辑放在后台线程中,你将会失败。

#3


0  

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

您的登录代码是否在UI线程上运行?这可能会阻止数据绑定更新。

#1


8  

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

您必须使您的登录异步。您可以使用BackgroundWorker执行此操作。就像是:

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 * for wpf doevents.

仅用于完整性:在登录发生之前,可以为UI提供刷新的时间。这是通过调度员完成的。然而,这是一个黑客攻击,IMO永远不应该被使用。但是如果您对此感兴趣,可以在*中搜索wpf doevents。

#2


2  

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

您可以尝试在单独的线程中运行busy indicar,如本文所述:在WPF中的单独线程中创建忙指示符

Or try running the new BusyIndicator from the Extended WPF Toolkit

或者尝试从Extended WPF Toolkit运行新的BusyIndi​​cator

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

但是我很确定如果你不将逻辑放在后台线程中,你将会失败。

#3


0  

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

您的登录代码是否在UI线程上运行?这可能会阻止数据绑定更新。