2

我正在使用一个外部框架,该框架用一个方法定义了一个接口:

bool Authenticate();

即包含身份验证的整个过程,包括用户交互(WinForms)。我想做的是:

bool Authenticate()
{
  bool succeeded = false;
  bool userCancelled = false;
  while(!succeeded && !userCancelled)
  {
     var credentials = AskTheUserForCredentials(); // this needs to wait for user input before returning!
     if (credentials == null) 
       userCancelled = true;
     else
       succeeded = AuthenticateWithAnExternalServer(credentials);

     if (!succeeded)
       ShowErrorMessage();
  }
  return succeeded;
}

AskTheUserForCredentials()现在实现的简单方法ShowErrorMessage()是在Form.ShowDialog()内部使用。这是非常糟糕的用户体验,因为实际身份验证过程的对话框消失了,并且错误消息出现在一个新的、必须单击以关闭对话框中。

我宁愿将它全部放在一个表单中,保持可见,适当地禁用文本框/按钮并自行显示错误消息。

在这个单一的阻塞方法调用中,您将如何做到这一点?

更新

迄今为止最好的解决方案是在内部实现一个消息泵AskTheUserForCredentials()

Credentials AskTheUserForCredentials()
{
   while(NeitherOkNorCancelPressed())
   {
      Application.DoEvents();
      Thread.Sleep(10); // Standard Sleep(0) results in 100% procesor core usage.
   }
   return CreateCredentialsFromTextboxesEtc();
}

现在我们都知道消息泵远非干净。

这个解决方案到底有多糟糕?

有更好的吗?

更新 2

消息泵有一些陷阱:

  • 丑陋且不完全使用 CPU

  • 使用 White UIAutomation 工作非常缓慢

我最终将整个过程委托给了 ChrisBD 的对话(对话仅在最终成功或失败后关闭)。这需要更多时间来使用 IoC 将身份验证从 GUI 中抽象出来,但最终是干净的并且可以按预期工作。

4

1 回答 1

1

我想你快到了。

显示一个具有用户输入控件的模式对话框,并让该对话框在需要时调用 Authenticate 方法。

然后,您可以选择何时关闭对话框以及显示任何错误消息的位置。

让模态对话框类的属性指示身份验证是否成功。当您关闭对话框类(在模态打开之前由主应用程序实例化)时,主应用程序将继续运行 - 然后您可以通过检查相应的对话框类属性来检查身份验证是否成功。

*在这里编辑 *

如果您自己实现 Authenticate 方法,那么调用模态对话框的是这个函数,而不是您的主应用程序(如前所述)。自定义表单类可以运行您的所有身份验证逻辑并显示您的用户交互控件以及任何错误消息。请记住删除最小化和关闭按钮并设置类属性以指示身份验证过程的成功或失败。

调用框架将等待您的身份验证方法的返回值。

于 2012-01-04T10:51:42.433 回答