【问题标题】:How can I force my busy indicator to display? (WPF)如何强制显示忙碌指示符? (WPF)
【发布时间】:2010-09-16 09:18:45
【问题描述】:

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

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

代码是:

        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 让我对 DoEvents 不寒而栗 ;-)

标签: wpf mvvm


【解决方案1】:

您必须使您的登录异步。您可以使用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();

仅出于完整性考虑:有可能在登录发生之前给 UI 刷新时间。这是通过调度程序完成的。然而,这是一个 hack,永远不应该使用 IMO。但如果您对此感兴趣,可以在 StackOverflow 中搜索 wpf doevents

【讨论】:

  • 废话。我希望这不是答案。我继承了一个巨大的应用程序,其中到处都有 UI 内容,我有一天将这个繁忙的指示器添加到大约 50 个屏幕上。没有更简单的方法吗?
  • 另一个问题是我在登录屏幕上尝试过,它破坏了测试:(
  • 可能是这样的:在 Login() 方法中,打开一个模式窗口 (window.ShowDialog) 并在其中进行登录。登录完成后关闭窗口。因此,在登录完成之前,该应用程序将被阻止。窗口本身显示应用程序正忙。在窗口内,我会使用 BackgroundWorker。
  • 我尝试了 DoEvents 的东西。奇怪的是,当我单击登录按钮时它工作正常。但是,如果我按 Enter 键(登录按钮是默认按钮),虽然运行完全相同的代码,但 doevents 的东西不起作用,忙指示符也不会显示。
  • 我知道这是一个旧线程,但也许这可能会在未来对某人有所帮助...如果您在许多不同的窗口上重复功能,请将该功能包装在自定义或用户控件中.这样,您只需实现一次,只需将登录位置的实例替换为“MyLoginControl”即可。这将使维护变得更加容易。 (重新)使用代码比在很多地方复制和粘贴代码要好得多——你会忘记在其他地方修复它。
【解决方案2】:

您可以尝试在单独的线程中运行繁忙的 indicar,如本文所述:Creating a Busy Indicator in a separate thread in WPF

或者尝试运行new BusyIndicator from the Extended WPF Toolkit

但我敢肯定,如果你不将逻辑放在后台线程中,你会很不走运。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2014-10-04
      • 2011-09-11
      • 2015-08-04
      • 2011-05-20
      • 1970-01-01
      • 2015-11-28
      • 1970-01-01
      • 2018-06-18
      • 2017-05-25
      相关资源
      最近更新 更多