我正在尝试为C#.NET控制台应用程序编写一个简单的箭头驱动选项菜单。给定字符返回类型的选项字典,用户可以选择带有向上/向下键的选项,并使用回车键选择它。
问题是,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 :(得分:0)
除了一个代码之外,你的代码没有问题,因为我在我的控制台应用程序中测试了它,因为if
中的ArrowDown
条件,所以永远不会选择最后一个选项,所以它会像:
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)
很明显,按Enter键控制台应用程序将退出,因为您从DoMenu
返回return options.Keys.ElementAt(answerIndex);
并且choice
变量将被选中。