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

8
我已经创建了一个忙碌指示器——基本上是一个旋转的徽标动画。我将其添加到登录窗口,并将Visibility属性绑定到我的ViewModel的BusyIndicatorVisibility属性。
当我点击登录时,我希望在登录过程中出现旋转效果(它调用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 而感到颤抖,加一分;-) - EightyOne Unite
3个回答

8

您需要将登录过程变为异步操作。您可以使用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留出时间来进行刷新。这是通过Dispatcher实现的。但是,这只是一种hack方法,我认为永远不应该使用。但如果您对此感兴趣,可以在StackOverflow上搜索wpf doevents


糟糕。我希望那不是答案。我继承了一个巨大的应用程序,UI方面的事情都发生在各个地方,而我只有一天时间将这个繁忙指示器添加到大约50个屏幕上。难道没有更简单的方法吗? - Unhappy
另一个问题是我在登录界面尝试过,但它会破坏测试 :( - Unhappy
也许可以这样做:在Login()方法中,打开模态窗口(window.ShowDialog)并在其中进行登录。完成登录后关闭窗口。因此,在完成登录之前应用程序将被阻塞。窗口本身显示应用程序正在忙碌中。在窗口中,我会使用BackgroundWorker。 - HCL
我尝试了DoEvents的东西。奇怪的是,当我点击登录按钮时,它可以正常工作。然而,如果我按Enter键(登录按钮是默认按钮),尽管运行的代码完全相同,但doevents的内容不起作用,繁忙指示器也不显示。 - Unhappy
我知道这是一个旧的帖子,但也许将来会有人受益...如果您在许多不同的窗口上重复使用功能,请将该功能封装在自定义或用户控件中。这样,您只需实现一次,然后用“我的登录控件”替换您的登录实例。这将使维护变得更加容易。重用代码比复制和粘贴到许多地方要好得多 - 您将忘记在其中一个其他地方修复它。 - Wonko the Sane

1

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接