2017-12-27 4 views
0

Ich versuche, ein einfaches, pfeilgesteuertes Optionsmenü für eine C# .NET-Konsolenanwendung zu schreiben. Bei einem Wörterverzeichnis mit Optionen für einen Zeichenrückgabetyp würden Benutzer eine Option mit ihren Auf-/Ab-Tasten auswählen und sie mit der Eingabetaste auswählen.C# Console-Menü: Escaping-Schleife nach Einzellauf

Problem ist, die switch-Anweisung bricht nach dem ersten Lauf vollständig aus dem Programm. Ich habe versucht, Haltepunkte setzen und es aus, bis keine Verfüg-


EDIT Bezifferung: Beschlossen trennen diesen Code von einigen der Asynchron-Code , die auch in die Klasse geschrieben wurde. Aus irgendeinem Grund lässt, dass es wie vorgesehen funktionieren, so .. jetzt muss ich herausfinden, warum async mit dieser Unordnung wäre, gibt es keine für eine Synchronisationsoperation benötigt await wie dieses ..


Code:

static char GetUserInput(Dictionary<char, String> options, int indent = 1) { 

     int optionAreaTop = Console.CursorTop; 
     Console.ForegroundColor = ConsoleColor.Yellow; 

     // First option, makes sure it's set in yellow 
     bool fo = true; 

     foreach (String opt in options.Values) { 
      Console.WriteLine(opt.PadLeft(indent + opt.Length, '\t')); 
      if (fo) { Console.ForegroundColor = ConsoleColor.White; fo = false; } 
     } 


     return DoMenu(options, optionAreaTop); 

    } 

    static char DoMenu(Dictionary<char, String> options, int optionAreaTop = 0) { 
     int answerIndex = 0; 
     int currentAnswerTop = optionAreaTop; 
     int indent = 2; 
     while (true) { 

      ConsoleKeyInfo kin = Console.ReadKey(true); 
      ConsoleKey ki = kin.Key; 

      switch (ki) { 
       case ConsoleKey.UpArrow: 
        if (currentAnswerTop - 1 >= optionAreaTop) { 
         // Rewrite selection in white 
         WriteOptionLine(currentAnswerTop, indent, options.Values.ElementAt(answerIndex), ConsoleColor.White); 
         WriteOptionLine(currentAnswerTop - 1, indent, options.Values.ElementAt(answerIndex - 1), ConsoleColor.Yellow); 
         currentAnswerTop -= 1; 
         answerIndex -= 1; 
        } 
        break; 

       case ConsoleKey.DownArrow: 
        if (answerIndex + 1 < options.Count - 1) { 
         // Rewrite selection in white 
         WriteOptionLine(currentAnswerTop, indent, options.Values.ElementAt(answerIndex), ConsoleColor.White); 
         WriteOptionLine(currentAnswerTop + 1, indent, options.Values.ElementAt(answerIndex + 1), ConsoleColor.Yellow); 
         currentAnswerTop += 1; 
         answerIndex += 1; 
        } 

        break; 

       case ConsoleKey.Enter: 
        return options.Keys.ElementAt(answerIndex); 

       default: 
        // Retry 
        break; 
      } 
     } 
    } 

    static void WriteOptionLine(int position, int indent, String option, ConsoleColor color) { 
     Console.SetCursorPosition(0, position); 
     Console.ForegroundColor = color; 
     Console.WriteLine(option.PadLeft(indent + option.Length, '\t')); 
    } 

Verbrauch:

Dictionary<char, String> opts = new Dictionary<char, string>(); 
opts.Add('r', "[R]etry the Download"); 
opts.Add('m', "[M]anually add the file"); 
opts.Add('s', "[S]kip the file"); 

// GET_USER_INPUT 
char choice = GetUserInput(opts, 2); 

// DO WHATEVER 
+0

Sie müssen eine Eingabetaste erhalten. – jdweng

+0

Ihre Frage scheint unvollständig zu sein. Wie hast du dein Programm debuggt und was hast du herausgefunden? – vasek

+0

Was ist das Problem, können Sie ein wenig klären? – Aria

Antwort

0

Die Re ist kein Problem mit Ihrem Code mit einer Ausnahme, wie ich es in meiner Konsolenanwendung kann die letzte Option getestet habe nie wegen Ihres if Zustandes in ArrowDown so gewählt werden, würde es so geändert werden:

case ConsoleKey.DownArrow: 
      if (answerIndex + 1 <= options.Count - 1) 
      { 
       // Rewrite selection in white 
       WriteOptionLine(currentAnswerTop, indent, options.Values.ElementAt(answerIndex), ConsoleColor.White); 
       WriteOptionLine(currentAnswerTop + 1, indent, options.Values.ElementAt(answerIndex + 1), ConsoleColor.Yellow); 
       currentAnswerTop += 1; 
       answerIndex += 1; 
      } 
      break; 

die if (answerIndex + 1 < options.Count - 1) sollte würden ausgewählte Option sein if (answerIndex + 1 <= options.Count - 1)

Es ist offensichtlich, dass die Enter-Taste Konsolenanwendung durch Drücken wird beendet, weil Sie von DoMenu von return options.Keys.ElementAt(answerIndex); und choice Variable zurückkehren.

+0

bemerkte, dass in einem schnellen Debug, hoppla. Code nicht um 5 Uhr, Leute. – RobotGryphon

+0

So ist es gelöst, ja? – Aria