我要做的是根据用户的按下来更改控制台。
所以我有一个带有以下三个选项的控制台:
> Option 1
Option 2
Option 3
基本上,如果用户按下向下箭头,则控制台将变为:
Option 1
> Option 2
Option 3
如果用户按下向上箭头,则控制台将返回到其初始状态。
我知道如何使用Console.ReadKey()读取用户的输入,但是我不知道如何修改已经写入的输出。
最后一件事是,当用户按下Enter键时,控制台不会创建新行,而是选择其中一个选项并调用委托。
答案 0 :(得分:1)
使用Console.ReadKey
和一些变量来保存所选选项的状态并不难。
以下代码是您所寻找的东西的非常快速和懒惰的实现。花一些时间自己重新编写它-这是让您了解如何实现所需的功能。
static void Main(string[] args)
{
bool IsRunning = true;
int Selected = 1;
while (IsRunning)
{
ConsoleKeyInfo NextKey = new ConsoleKeyInfo();
if (Selected < 1)
Selected = 3;
else if (Selected > 3)
Selected = 1;
Console.Clear();
if (Selected == 1)
Console.Write("> ");
Console.WriteLine("Option 1");
Console.WriteLine();
if (Selected == 2)
Console.Write("> ");
Console.WriteLine("Option 2");
Console.WriteLine();
if (Selected == 3)
Console.Write("> ");
Console.WriteLine("Option 3");
Console.WriteLine();
Console.Write("Choose an option (Q to Quit): ");
while (!(NextKey.Key == ConsoleKey.DownArrow ||
NextKey.Key == ConsoleKey.UpArrow ||
NextKey.Key == ConsoleKey.Q ||
(NextKey.KeyChar >= '1' &&
NextKey.KeyChar <= '3')))
{
NextKey = Console.ReadKey();
}
switch (NextKey.Key)
{
case ConsoleKey.D1:
// Do something
break;
case ConsoleKey.D2:
// Do something
break;
case ConsoleKey.D3:
// Do something
break;
case ConsoleKey.DownArrow:
Selected++;
break;
case ConsoleKey.UpArrow:
Selected--;
break;
case ConsoleKey.Q:
IsRunning = false;
break;
}
}
}
在没有按'Q'键退出应用程序的情况下,代码将循环播放。
按下向下或向上箭头将在可用选项中旋转。
按1、2或3时,将使// Do something
语句内的switch
行运行。您应该在这里为每个选项调用任何存在的功能。
为了使用所选选项更新“菜单”,请清除控制台输出,然后重新输出。通过Selected
变量标识正确的选项。
还有其他几种方法可以实现上述目的,但更为简洁。我想给你一个从哪里开始的想法。我并不是说这是最好或最整洁的解决方案。
编辑
发生想法-您想使用Enter选择该选项。
我已经稍微修改了代码以提供该功能:
while (!(NextKey.Key == ConsoleKey.DownArrow ||
NextKey.Key == ConsoleKey.UpArrow ||
NextKey.Key == ConsoleKey.Q ||
NextKey.Key == ConsoleKey.Enter))
{
NextKey = Console.ReadKey();
}
switch (NextKey.Key)
{
case ConsoleKey.Enter:
// Do something depending on Selected option
switch (Selected)
{
case 1:
// Do something
break;
case 2:
// Do something
break;
case 3:
// Do something
break;
}
break;
case ConsoleKey.DownArrow:
...
答案 1 :(得分:0)
这是一种类似的方法,只需要较少的代码,它隐藏了光标并显示了我们自己的指示所选菜单项的自定义光标。
该方法采用菜单标题,供用户选择的选项列表以及光标字符。它打印出页眉和下划线,然后打印每个选项,每个选项前带有3个空格。然后,将光标移动到第一个选项(第二行,因为标头为0,下划线为1,空格为2,所以行索引为3),第二个字符,然后写一个退格字符,后跟光标(退格删除了第一个字符,因此我们可以写一个新的。)
当用户按下键时,我们仅处理上下箭头和Enter键。通过将true
传递到Console.ReadKey()
,用户输入将被“丢弃”,并且不会显示在窗口中。这样一来,我们switch
只能使用我们关心的键。
当他们按下箭头键时,我们将光标移动到当前行的第二列,先打印一个退格键,然后再打印一个空格(以擦除旧光标),然后上下移动一行,然后从第二列开始我们先打印退格键,然后再打印光标字符。
当用户按下Enter
时,我们再次启用控制台光标,并返回光标所在的行以指示当时选择了哪个项目:
private static int GetMenuChoice(string header, List<string> options, char cursor = '>')
{
// Clear console and hide cursor
Console.Clear();
Console.CursorVisible = false;
// Write our header with an underline
Console.WriteLine(" " + header);
Console.WriteLine(" " + new string('-', header.Length));
Console.WriteLine();
// Write out each option with spaces before it
options.ForEach(option => Console.WriteLine($" {option}"));
// Move to the first option and, from the second character,
// write a backspace and then the cursor symbol
Console.SetCursorPosition(1, 3);
Console.Write($"\b{cursor}");
// Move cursor when user presses arrow keys, and get selection when they press enter
while (true)
{
// Pass 'true' to ReadKey so the input is not written
var input = Console.ReadKey(true);
switch (input.Key)
{
case ConsoleKey.UpArrow:
if (Console.CursorTop > 3)
{
Console.CursorLeft = 1;
Console.Write("\b ");
Console.SetCursorPosition(1, Console.CursorTop - 1);
Console.Write($"\b{cursor}");
}
break;
case ConsoleKey.DownArrow:
if (Console.CursorTop < options.Count + 2)
{
Console.CursorLeft = 1;
Console.Write("\b ");
Console.SetCursorPosition(1, Console.CursorTop + 1);
Console.Write($"\b{cursor}");
}
break;
case ConsoleKey.Enter:
var selection = Console.CursorTop - 3;
Console.CursorVisible = true;
Console.SetCursorPosition(0, options.Count + 4);
return selection;
}
}
}
这可以通过示例ATM菜单进行测试:
private static void Main()
{
var options = new List<string>
{
"Open a new account",
"Deposit Money",
"Withdraw money",
"Check balance",
"Exit"
};
var selectedItem = GetMenuChoice("ATM Machine", options);
Console.WriteLine($"You selected option: '{options[selectedItem]}'");
GetKeyFromUser("\nDone! Press any key to exit...");
}
输出