I am making a basic Console application (unfortunately this is a must) that shows the time and a very basic interface where a user can enter an option. When they do, the UI updates with relevant new data to display and allows further input and so on. All the while, a live clock with seconds is shown at the top.
What I am basically doing is redrawing the whole UI every second and attempting to listen to the user input to direct how the UI is drawn next time around. How do I manage the user input while redrawing the UI? Is there a better way?
Here is the whole (very cut down verion of) program:
using System;
using System.Diagnostics;
using System.Timers;
namespace TimerTest
{
class Program
{
static bool useStartUI = false;
static string currentInput = "";
static Timer aTimer = new System.Timers.Timer();
static void Main(string[] args)
{
aTimer.Elapsed += new ElapsedEventHandler(DrawUI);
aTimer.Interval = 1000;
aTimer.Enabled = true;
Console.ReadLine();
currentInput = Console.ReadLine();
}
static void DrawUI(object source, ElapsedEventArgs e)
{
Debug.WriteLine("currentInput = " + currentInput);
if (currentInput == "A")
{
useStartUI = true;
} else
{
useStartUI = false;
}
if (!useStartUI)
{
DisplayStartUI();
}
else
{
DisplayCurrentUI();
}
}
private static void DisplayStartUI()
{
Console.Clear();
Console.WriteLine("DisplayStartUI - " + DateTime.Now.ToString("HH:mm:ss tt"));
Console.WriteLine("Press 'B' to switch to CurrentUI");
Console.ReadLine();
currentInput = Console.ReadLine();
}
private static void DisplayCurrentUI()
{
Console.Clear();
Console.WriteLine("DisplayCurrentUI - " + DateTime.Now.ToString("HH:mm:ss tt"));
Console.WriteLine("Press 'A' to switch to StartUI");
Console.ReadLine();
currentInput = Console.ReadLine();
}
}
}
At the moment I have the Console.ReadLine();
right after the timer is fired, if I don't then the application opens and closes straight away. The other two Console.ReadLine();
are ignored completely but it is at these points I would have expected user input to be recorded.
Seems I was over thinking this and @elgonzo pointed me in the right direction. I now just have the timer display on one line and clear other lines as and when I need them. I have a basic working example that I will expand my main program into. It appears to do exactly what I need (obviously missing validation and functionality) please comment if this can be improved upon:
using System;
using System.Diagnostics;
using System.Timers;
namespace TimerTest
{
class Program
{
static bool appOpen = true;
static bool useStartUI = false;
static string currentInput = "";
static Timer aTimer = new System.Timers.Timer();
static void Main(string[] args)
{
Console.WriteLine("Main - " + DateTime.Now.ToString("HH:mm:ss tt"));
aTimer.Elapsed += new ElapsedEventHandler(DrawClock);
aTimer.Interval = 1000;
aTimer.Enabled = true;
while (appOpen) // to keep the application running and give a possible exit - will expand this
{
DrawUI();
}
}
#region UI region
static void DrawClock(object source, ElapsedEventArgs e)
{
Console.SetCursorPosition(0, 0);
Console.WriteLine("DrawClock - " + DateTime.Now.ToString("HH:mm:ss tt"));
Console.SetCursorPosition(0, 7);
}
static void DrawUI()
{
Debug.WriteLine("currentInput = " + currentInput);
if (currentInput == "A" || currentInput == "a")
{
useStartUI = true;
}
else if (currentInput == "B" || currentInput == "b")
{
useStartUI = false;
}
if (useStartUI)
{
DisplayStartUI();
}
else
{
DisplayCurrentUI();
}
}
private static void DisplayStartUI()
{
CleanUI();
Console.WriteLine("DisplayStartUI");
Console.WriteLine("Press 'B' to switch to CurrentUI");
ConsoleKeyInfo keyPressed = Console.ReadKey();
Console.SetCursorPosition(0, 7);
Console.WriteLine("You pressed {0}", keyPressed.KeyChar);
currentInput = keyPressed.KeyChar.ToString();
if (keyPressed.KeyChar.ToString() == "b")
{
DrawUI();
}
}
private static void DisplayCurrentUI()
{
CleanUI();
Console.WriteLine("DisplayCurrentUI");
Console.WriteLine("Press 'A' to switch to StartUI");
ConsoleKeyInfo keyPressed = Console.ReadKey();
Console.SetCursorPosition(0, 7);
Console.WriteLine("You pressed {0}", keyPressed.KeyChar);
currentInput = keyPressed.KeyChar.ToString();
if (keyPressed.KeyChar.ToString() == "a")
{
DrawUI();
}
}
#endregion
#region functional methods
public static void CleanUI()
{
Console.SetCursorPosition(0, 5);
ClearCurrentConsoleLine();
Console.SetCursorPosition(0, 6);
ClearCurrentConsoleLine();
Console.SetCursorPosition(0, 7);
ClearCurrentConsoleLine();
Console.SetCursorPosition(0, 5);
}
public static void ClearCurrentConsoleLine()
{
int currentLineCursor = Console.CursorTop;
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, currentLineCursor);
}
#endregion
}
}