2015-12-12 2 views
1

Я начинаю OOP и C#.Как правильно приостановить/задержать приложение Windows Forms

Я работаю над викториной с использованием Windows Forms. Моя проблема связана с двумя классами: Форма и логика игры. У меня есть базовый интерфейс с классическими элементами управления Froms. Взглянуть.

UI layout

То, что я хочу добиться того, когда игрок нажимает любую кнопку ответа, он будет higlight, что нажата кнопка красным или зеленым цветом, в зависимости от того, правильно ли это или неправильного ответа. После изменения цвета я хочу, чтобы программа подождала некоторое время, а затем переходите к следующему вопросу.

Probelm - это то, что я не знаю, как добиться этого правильно. Я не знаю, как работать с потоками и как работает приложение Form, связанное с потоками. Должен ли я использовать спящий поток или таймер или асинхронный режим?

Я покажу вам метод в игровом классе, который должен справиться с этим.

public static void Play(char answer) //Method gets a char representing a palyer answer 
    { 
     if (_rightAnswer == answer) //If the answer is true, the button should become green 
     { 
      Program.MainWindow.ChangeBtnColor(answer, System.Drawing.Color.LightGreen); 
      _score++; 
     } 
     else //Otherwise the button becomes Red 
     { 
      Program.MainWindow.ChangeBtnColor(answer, System.Drawing.Color.Red); 
     } 

     //SLEEP HERE 

     if (!(_currentIndex < _maxIndex)) //If it is the last question, show game over 
     { 
      Program.MainWindow.DisplayGameOver(_score); 
     } 
     else //If it is not the last question, load next question and dispaly it and finally change the button color to default 
     { 
      _currentIndex++; 
      _currentQuestion = Database.ListOfQuestions.ElementAt(_currentIndex); 
      _rightAnswer = _currentQuestion.RightAnswer; 
      Program.MainWindow.DisplayStats(_score, _currentIndex + 1, _maxIndex + 1); 
      Program.MainWindow.DisplayQuestion(_currentQuestion.Text); 
      Program.MainWindow.DisplayChoices(_currentQuestion.Choices); 
     } 
     Program.MainWindow.ChangeBtnColor(answer, System.Drawing.SystemColors.ControlLight); 
    } 

Я не хочу, чтобы полностью блокировать пользовательский интерфейс, но и я не хочу, чтобы пользователи других событий, нажимая на другие кнопки во время паузы. Потому что это приведет к неправильному запуску приложения.

ответ

0

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

-1

вы можете положить Thread.sleep (время в милли второй)

Program.MainWindow.ChangeBtnColor(answer,System.Drawing.SystemColors.ControlLight); 
Thread.sleep(5000); 

в течение 5 секунд задержки.

+3

Это заблокирует пользовательский интерфейс. – ChrisF

+0

[Thread.Sleep] (https://msdn.microsoft.com/en-us/library/d00bd51t.aspx) таймаут измеряется в миллисекундах, а не в наносекундах. Очень большая разница. –

0

Как только пользователь выбрал ответ, вы можете отключить все кнопки, чтобы они не могли нажать что-либо еще.

Затем запустите таймер, чтобы не блокировать пользовательский интерфейс. Таймер : в основном поток, но обрабатывает все потоки для вас, поэтому вам не нужно беспокоиться об этом.

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

0

В // СНА ЗДЕСЬ добавить эту строку кода

Timer timer = new Timer(new TimerCallback(timerCb), null, 2000, 0); 

The 2000 является миллисекунды и время ожидания, timerCb является обратный вызов метода.

Также под этим отключите все ваши кнопки, чтобы новые события не генерировались.

private void timerCb(object state) 
    { 
     Dispatcher.Invoke(() => 
     { 
      label1.Content = "Foo!";    
     }); 
    } 

Вы можете делать все, что вы хотите в обратный вызов, однако, если вы делаете что-то, что могло бы изменить что-либо в пользовательском интерфейсе, вы должны использовать Dispatcher, как я изменить содержание метки.

0

Приостановка выполнения в сценарии GUI очень легко благодаря await:

await Task.Delay(2000); 

Это не блокирует пользовательский интерфейс.

Вам следует изучить, что делает await и как его использовать. Если вы никогда не слышали об этом и программируете WinForms, вы делаете что-то неправильно.

Нет необходимости в таймерах или потоках. Нет обратных вызовов, нет Invoke.