2017-05-18 4 views
-2

Je travaille sur un projet appelé IAT. En deux mots, il y a 2 catégories dans les coins supérieurs (gauche, droite), et une liste de mots, reliés à ces catégories, affichés aléatoirement au centre de l'écran (1 mot correspond à une seule catégorie). Après que le mot est affiché au milieu, le programme devrait "s'arrêter" et attendre que l'utilisateur appuie sur la touche pour trier le mot (flèche gauche pour la catégorie gauche et droite pour la droite). Après que l'utilisateur a donné une réponse, le programme compte le temps perdu sur les réponses. Ensuite, l'autre mot est montré et ce processus continue pour plusieurs itérations.
En résumé, je veux faire l'équivalent de RedKey(). Pendant le débogage, j'ai réalisé que le programme ne réagit pas aux touches enfoncées dans while (true/stopwatch.IsRunning()/etc). Que dois-je faire pour que le programme attende la réponse de l'utilisateur et réagisse-t-il?wpf keyDown dans while loop

+0

Vous devez montrer le code problématique. Exécutez-vous des boucles dans le thread d'interface utilisateur? Pour organiser le timeout en attendant l'action de l'utilisateur, vous pouvez utiliser un simple "Timer". Pour mesurer l'heure - 'Stopwatch' ou' DateTime.Now'. – Sinatr

Répondre

0

Lorsque le programme affiche un mot, vous devriez commencer à minuterie (en utilisant System.Timers.Timer), gérer son événement Ellapsed, à l'intérieur gestionnaire que vous avez à incrémenter variable qui sera votre compteur (comment les réponses à long utilisateur question) Puis dans l'événement KeyDown de MainWindow vous pouvez vérifier si la touche enfoncée est la flèche gauche ou droite, puis si la minuterie est activée, si vous savez que la question est prête à être répondue, maintenant arrêtez la minuterie nombre de secondes pendant lesquelles l'utilisateur appuie sur la flèche (bien sûr, vous devez ajuster l'intervalle du temporisateur).

Ici vous avez le code complet (sans questions simplement logique bien sûr)

public partial class MainWindow : Window 
{ 
    Timer answerTimeTimer; // it's for counting time of answer 
    Timer questionTimer; // this is used for generating questions 
    int timeOfAnswer; 

    public MainWindow() 
    { 
     InitializeComponent(); 


     questionTimer = new Timer() 
     { 
      Interval = 2500 
     }; 


     answerTimeTimer = new Timer() 
     { 
      Interval = 1000 
     }; 

     answerTimeTimer.Elapsed += AnswerTimeTimer_Elapsed; 
     questionTimer.Elapsed += QuestionTimer_Elapsed; 

     questionTimer.Start(); 
    } 

    private void QuestionTimer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     AskQuestion(); 
    } 

    private void AskQuestion() 
    { 
     //Your questions logic 
     Console.WriteLine("Question asked"); 
     Dispatcher.Invoke(new Action(() => label.Content = "Question asked")); // This line is just to update the label's text (it's strange because you need to update it from suitable thread) 
     answerTimeTimer.Start(); 
     questionTimer.Stop(); 
    } 

    private void AnswerTimeTimer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     timeOfAnswer++; 
     Dispatcher.Invoke(new Action(() => label.Content = timeOfAnswer)); 
    } 

    private void Window_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.Key == Key.Left || e.Key == Key.Right) 
     { 
      if (answerTimeTimer.Enabled) 
      { 
       answerTimeTimer.Stop(); 
       //Here you can save the time from timeOfAnswer 
       Console.WriteLine("Question answered in " + timeOfAnswer); 
       Dispatcher.Invoke(new Action(() => label.Content = "Question answered in " + timeOfAnswer)); 
       timeOfAnswer = 0; // Reset time for the next question 
       questionTimer.Start(); 

      } 
     } 
    } 


} 

Et une étiquette en XAML pour montrer que tout fonctionne

<Label x:Name="label" Content="Right or left" HorizontalAlignment="Left" Margin="125,72,0,0" VerticalAlignment="Top"/> 

Si vous avez des questions il suffit de demander: