Search code examples
c#consolekeyreadlinehotkeys

Listen on ESC while reading Console line


I want to read an users input into a string while still reacting on ESC press at any time, but without defining a system wide hotkey.

So when the user types e. g. "Test Name" but instead of confirming with ENTER presses ESC he should be led back into main menu.

Console.Write("Enter name: ")
if (Console.ReadLine().Contains(ConsoleKey.Escape.ToString()))
{
    goto MainMenu;
}
return Console.ReadLine();

Thats the simplest way I could think of, but since ESC is not seen by Console.ReadLine() it is not working.

Found a rather complex way to react on ESC when pressed before starting to enter text here, but I want it to work at any time.


Solution

  • You will probably have to forego the use of ReadLine and roll your own using ReadKey:

    static void Main(string[] args)
    {
        Console.Clear();
        Console.Write("Enter your name and press ENTER.  (ESC to cancel): ");
        string name = readLineWithCancel();
    
        Console.WriteLine("\r\n{0}", name == null ? "Cancelled" : name);
    
        Console.ReadLine();
    }
    
    //Returns null if ESC key pressed during input.
    private static string readLineWithCancel()
    {
        string result = null;
    
        StringBuilder buffer = new StringBuilder();
    
        //The key is read passing true for the intercept argument to prevent
        //any characters from displaying when the Escape key is pressed.
        ConsoleKeyInfo info = Console.ReadKey(true);
        while (info.Key != ConsoleKey.Enter && info.Key != ConsoleKey.Escape)
        {
            Console.Write(info.KeyChar);
            buffer.Append(info.KeyChar);
            info = Console.ReadKey(true);
        } 
    
        if (info.Key == ConsoleKey.Enter)
        {
            result = buffer.ToString();
        }
    
        return result;
    }
    

    This code is not complete and may require work to make it robust, but it should give you some ideas.