2017-12-27 9 views
0

C#.NETコンソールアプリケーション用の簡単な矢印駆動オプションメニューを作成しようとしています。文字戻り型のオプションの辞書があれば、ユーザーは上/下キーでオプションを選択し、Enterキーで選択します。C#コンソールメニュー:1回実行した後にループをエスケープする

問題は、switch文が最初の実行後に完全にプログラムから抜けることです。また、クラスに書き込まれた非同期コード の一部から、このコードを分離することを決めた:私はノー見れる


編集するには、ブレークポイントを配置し、それを考え出すしようとしました。意図した通りに動作し をすることができますどのような理由については、..だから今、私は非同期で このいじりられる理由を把握する必要があり、なしは このような同期操作のために必要が待っています。..


コード:

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')); 
    } 

は使用方法:

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

Enterキーを取得する必要があります。 – jdweng

+0

あなたの質問は不完全なようです。あなたはどのようにあなたのプログラムをデバッグしましたか、あなたは何を見つけましたか? – vasek

+0

何が問題なのですか、ちょっと分かりますか? – Aria

答えて

0

1を除いて、あなたのコードに問題はありません、私は私のコンソールアプリでそれをテストしてきたように、最後のオプションがArrowDownであるため、あなたのif条件を選択することはできないんので、それは次のように変更される再:

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; 

if (answerIndex + 1 < options.Count - 1)べきif (answerIndex + 1 <= options.Count - 1)

あなたがオプションを選択されるreturn options.Keys.ElementAt(answerIndex);choice変数でDoMenuから戻ってきているので、Enterキーコンソールアプリケーションを押して終了しますことは明らかであること。

+0

クイックデバッグでは、それは気付いています。午前5時にコード化しないでください。 – RobotGryphon

+0

それで解決しました、はい? – Aria

関連する問題