Как инкапсулировать взаимодействие с пользователем в одном методе - PullRequest
2 голосов
/ 04 января 2012

Я использую внешнюю платформу, которая определяет интерфейс одним методом:

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

Насос сообщений имел несколько ловушек:

  • был уродлив и не полностью эффективен с процессором

  • работал ужасно медленно с белым UIAutomation

В итоге я делегировал весь процесс диалогу как ChrisBD (диалог закрывается только после окончательного успеха или неудачи).Это заняло больше времени, чтобы абстрагировать аутентификацию от GUI с помощью IoC, но в конечном итоге все чисто и работает как задумано.

1 Ответ

1 голос
/ 04 января 2012

Я думаю, что вы почти у цели.

Отобразите модальное диалоговое окно, в котором есть пользовательские элементы управления вводом, и когда это диалоговое окно вызывает метод Authenticate при необходимости.

Затем можно выбрать, когдадиалоговое окно должно закрыться, и в действительности там, где отображается любое сообщение об ошибке.

Свойство класса модального диалогового окна указывает, была ли аутентификация успешной или нет.Когда вы закрываете класс диалога (который был создан вашим основным приложением до того, как он открыл его модально), основное приложение продолжит работать - вы можете проверить, прошла ли аутентификация успешно или нет, проверив соответствующее свойство класса диалога.

* отредактировано здесь *

Если вы сами реализуете метод Authenticate, то именно эта функция вызывает модальное диалоговое окно, а не ваше основное приложение (как было сказано ранее).).Пользовательский класс формы может запускать всю вашу логику аутентификации и отображать ваши элементы управления взаимодействием с пользователем, а также любые сообщения об ошибках.Не забудьте удалить кнопки свертывания и закрытия и установить свойство класса, чтобы указать успешность или неудачу процесса аутентификации.

Вызывающая структура будет ожидать возвращаемого значения вашего метода аутентификации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...