One way to do this is to use a combination of Console.SetCursorPosition
and Console.Write
to set the cursor to the beginning of their response, write enough whitespace to "erase" their reaponse, and then set the cursor back to the beginning again.
For example:
static string GetUserInput(string prompt, List<string> validResponses)
{
Console.Write(prompt);
// Capture the cursor position just after the prompt
var inputCursorLeft = Console.CursorLeft;
var inputCursorTop = Console.CursorTop;
// Now get user input
string input = Console.ReadLine();
while (validResponses != null &&
validResponses.Any() &&
!validResponses.Contains(input, StringComparer.OrdinalIgnoreCase))
{
Console.ForegroundColor = ConsoleColor.Red;
// PadRight ensures that this line extends the width
// of the console window so it erases itself each time
Console.Write($"Error! '{input}' is not a valid response".PadRight(Console.WindowWidth));
Console.ResetColor();
// Set cursor position to just after the promt again, write
// a blank line, and reset the cursor one more time
Console.SetCursorPosition(inputCursorLeft, inputCursorTop);
Console.Write(new string(' ', input.Length));
Console.SetCursorPosition(inputCursorLeft, inputCursorTop);
input = Console.ReadLine();
}
// Erase the last error message (if there was one)
Console.Write(new string(' ', Console.WindowWidth));
return input;
}
In use this might look like:
static void Main(string[] args)
{
var validResponses = new List<string> {"Yes", "No"};
var userInput = GetUserInput("Do you like me? ", validResponses);
if (userInput.Equals("Yes", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("I like you too!");
}
else
{
Console.WriteLine("And all along I thought you had good taste.");
}
GetKeyFromUser("\nDone! Press any key to exit...");
}
Here's a sample run of the program. I had to include several screenshots since the response (and then the error message) are cleared on each iteration:
