class menu
{
string[] elements;
public menu(string[] ele) { elements = ele; }
public menu() : this(new string[3]) { }
public void dispMenu(int sel)
{
Console.Clear();
Console.SetCursorPosition(0, 0);
for (int i = 0; i != elements.Length; i++)
{
if (i != sel) { Console.WriteLine(" " + elements[i]); }
else { Console.WriteLine(">" + elements[i] + "<"); }
}
}
public int doMenu()
{
int selection = 0;
do
{
dispMenu(selection);
while (!Console.KeyAvailable)
{
}
if (Console.ReadKey().Key == ConsoleKey.UpArrow)
{
if (selection == 0) { selection = elements.Length; }
else { selection--; }
}
else if (Console.ReadKey().Key == ConsoleKey.DownArrow)
{
if (selection == elements.Length) { selection = 0; }
else { selection++; }
}
} while (Console.ReadKey(true).Key != ConsoleKey.Enter);
return selection;
}
}
class Program
{
static void Main(string[] args)
{
menu swag = new menu(new string[3] {"Swag", "Money", "yolo"});
Console.WriteLine(swag.doMenu());
Console.Read();
}
}
为什么会挂断?它是一个菜单对象,它应该响应向上和向下箭头,并在按下enter时终止,返回选择。在运行时它可以工作,但是你必须按几次键才能让它注册。 enter键也表现为这种方式。
答案 0 :(得分:1)
在进行所有比较之前,将Console.ReadKey()结果分配给变量一次。否则我相信它会在每次遇到条件时尝试读取输入。现在你做了三次,所以第一次按键时它只会比较UpArrow的条件,第二次 - 对于DownArrow,第三次 - 仅对于Enter,所以你必须按几次键才能处理。 你的doMenu方法有类似的东西:
public int doMenu()
{
int selection = 0;
ConsoleKeyInfo consoleKeyInfo;
do
{
dispMenu(selection);
while (!Console.KeyAvailable)
{
}
consoleKeyInfo = Console.ReadKey();
if (consoleKeyInfo.Key == ConsoleKey.UpArrow)
{
if (selection == 0) { selection = elements.Length; }
else { selection--; }
}
else if (consoleKeyInfo.Key == ConsoleKey.DownArrow)
{
if (selection == elements.Length) { selection = 0; }
else { selection++; }
}
} while (consoleKeyInfo.Key != ConsoleKey.Enter);
return selection;
}
答案 1 :(得分:1)
Console.ReadKey()
方法返回用户按下的下一个字符或功能键。您在循环中多次调用此方法,因此第一个调用读取第一个键,第二个调用读取第二个键,依此类推。除非您在正确的时刻点击正确的密钥,否则您的代码无法正常工作。
ReadKey方法等待,即发出ReadKey方法的线程上的块,直到按下字符或功能键
所以检查空!Console.KeyAvailable
的循环是不必要的。
代码可以简化如下
public int doMenu() {
int selection = 0;
ConsoleKeyInfo key = null;
do {
dispMenu(selection);
key = Console.ReadKey();
if (key.Key == ConsoleKey.UpArrow)
{
if (selection == 0) { selection = elements.Length; }
else { selection--; }
}
else if (key.Key == ConsoleKey.DownArrow)
{
if (selection == elements.Length) { selection = 0; }
else { selection++; }
}
} while (key.Key != ConsoleKey.Enter);
return selection;
}
答案 2 :(得分:0)
就像Console.ReadLine()函数一样,每次出现函数时,它都会暂停程序以接收输入。正如raderick所说,你应该将ReadKey分配给一个变量,所以它只要求输入一次。