C
C#2y ago
Rémi

❔ Interactive both in y and x axis, in cmd

Hello :), I am trying to do an interactive menu in a command line application that use both the x and y axis, you navigate using keyboard arrows. I did a well working one that is only using the x axis, but with both this is way more complicated. I wrote a code that kind of works but for any reason the Console.Clear is not doing what i was expecting :
public static void Editing()
{
int x = 0;
int y = 0;
List<Option> x_options = new List<Option>();
List<string> y_options = GetPrompt();
List<string> special = new List<string>() { "%path", "%user", "%os", "%workingset", "%time", "%date", "%newline" };
List<string> colors = new List<string>() { "%fore:", "%back:", "%style:" };
while (true)
{
if (special.Contains(y_options[y]) || colors.Contains(y_options[y]))
{
x_options.Add(new Option(CustomCMD.GetValue("tips"), () => { }));
}
x_options.Add(new Option(CustomCMD.GetValue("edit"), () => { }));
x_options.Add(new Option(CustomCMD.GetValue("add_right"), () => { }));
x_options.Add(new Option(CustomCMD.GetValue("add_left"), () => { }));
x_options.Add(new Option(CustomCMD.GetValue("delete"), () => { }));

WriteComplexMenu(x_options, y_options, x_options[x], y_options[y]);
ConsoleKeyInfo key = Console.ReadKey();
if (key.Key == ConsoleKey.RightArrow)
{
y--;
if (y < 0) y = y_options.Count - 1;
}
else if (key.Key == ConsoleKey.LeftArrow)
{
y++;
if (y >= y_options.Count) y = 0;
}
else if (key.Key == ConsoleKey.UpArrow)
{
x--;
if (x < 0) x = x_options.Count - 1;
}
else if (key.Key == ConsoleKey.DownArrow)
{
x++;
if (x >= x_options.Count) x = 0;
}
else if (key.Key == ConsoleKey.Enter)
{
}
}
}

private static void WriteComplexMenu(List<Option> x_options, List<string> y_options, Option x_selected, string y_selected, string title="", string end="")
{
Console.Clear();
if (title != "") Console.WriteLine(title);
foreach (Option option in x_options)
{
if (option == x_selected)
{
Console.Write(" > ");
}
else
{
Console.Write(" ");
}
Console.WriteLine(option.Name);
}
Console.WriteLine(end);
int tab = 0;
bool found = false;
foreach (string option in y_options)
{
if (option == y_selected)
{
found = true;
tab += Math.Abs(option.Length / 2);
}
else if (!found)
{
tab += option.Length + 1;
}
Console.Write(option + " ");
}
Console.WriteLine();
for (int i = 0; i < tab; i++)
{
Console.Write(" ");
}
Console.Write("^");
}
class Option
{
public string Name { get; }
public Action Selected { get; }

public Option(string name, Action selected)
{
Name = name;
Selected = selected;
}
}
public static void Editing()
{
int x = 0;
int y = 0;
List<Option> x_options = new List<Option>();
List<string> y_options = GetPrompt();
List<string> special = new List<string>() { "%path", "%user", "%os", "%workingset", "%time", "%date", "%newline" };
List<string> colors = new List<string>() { "%fore:", "%back:", "%style:" };
while (true)
{
if (special.Contains(y_options[y]) || colors.Contains(y_options[y]))
{
x_options.Add(new Option(CustomCMD.GetValue("tips"), () => { }));
}
x_options.Add(new Option(CustomCMD.GetValue("edit"), () => { }));
x_options.Add(new Option(CustomCMD.GetValue("add_right"), () => { }));
x_options.Add(new Option(CustomCMD.GetValue("add_left"), () => { }));
x_options.Add(new Option(CustomCMD.GetValue("delete"), () => { }));

WriteComplexMenu(x_options, y_options, x_options[x], y_options[y]);
ConsoleKeyInfo key = Console.ReadKey();
if (key.Key == ConsoleKey.RightArrow)
{
y--;
if (y < 0) y = y_options.Count - 1;
}
else if (key.Key == ConsoleKey.LeftArrow)
{
y++;
if (y >= y_options.Count) y = 0;
}
else if (key.Key == ConsoleKey.UpArrow)
{
x--;
if (x < 0) x = x_options.Count - 1;
}
else if (key.Key == ConsoleKey.DownArrow)
{
x++;
if (x >= x_options.Count) x = 0;
}
else if (key.Key == ConsoleKey.Enter)
{
}
}
}

private static void WriteComplexMenu(List<Option> x_options, List<string> y_options, Option x_selected, string y_selected, string title="", string end="")
{
Console.Clear();
if (title != "") Console.WriteLine(title);
foreach (Option option in x_options)
{
if (option == x_selected)
{
Console.Write(" > ");
}
else
{
Console.Write(" ");
}
Console.WriteLine(option.Name);
}
Console.WriteLine(end);
int tab = 0;
bool found = false;
foreach (string option in y_options)
{
if (option == y_selected)
{
found = true;
tab += Math.Abs(option.Length / 2);
}
else if (!found)
{
tab += option.Length + 1;
}
Console.Write(option + " ");
}
Console.WriteLine();
for (int i = 0; i < tab; i++)
{
Console.Write(" ");
}
Console.Write("^");
}
class Option
{
public string Name { get; }
public Action Selected { get; }

public Option(string name, Action selected)
{
Name = name;
Selected = selected;
}
}
Editing is the main code that run the menu and handle the user input
19 Replies
Rémi
RémiOP2y ago
CustomCMD.GetValue() is used to get the correct string, depends of the language (this is not the actual problem so i won't explain much) this is what is display without any input (and this is what i want) :
Rémi
RémiOP2y ago
Rémi
RémiOP2y ago
But once I do any input, the selected item is the good one, but the console is acting wierd :
Rémi
RémiOP2y ago
It duplicates the menu why
phaseshift
phaseshift2y ago
i didnt see where you clear the screen
Rémi
RémiOP2y ago
in the begining of WriteComplexMenu which is called right after defining every option in the while loop
phaseshift
phaseshift2y ago
but every time you loop, dont you add more options? so on the second time you have 2x each option? $debug is your friend
MODiX
MODiX2y ago
Tutorial: Debug C# code - Visual Studio (Windows)
Learn features of the Visual Studio debugger and how to start the debugger, step through code, and inspect data in a C# application.
Rémi
RémiOP2y ago
i can't debug because of the way i'm compiling I need to read json files, that are in the CustomCMD folder, but the compiled exe goes to CustomCMD/Debug/net7.0 this is this 🥲 it has been 2 hours while I was reading everything about buffer, Console.Clear thing etc ... x)
phaseshift
phaseshift2y ago
add a sleep to your program. while it is sleeping, atach to the running process
Rémi
RémiOP2y ago
wdym by atach?
phaseshift
phaseshift2y ago
phaseshift
phaseshift2y ago
you can connect a debugger to a running process
Rémi
RémiOP2y ago
nice, is there a way to do it automatically right after the build ? right now it's moving the exe and other file automatically from net7.0 to the right folder usig a .bat script
phaseshift
phaseshift2y ago
you'd be better off making the location that json files are read-from a command line argument ( and dont use a bat script to move the exe to a 'special' location) you can control the commandline args given when doing normal 'debug' from the project properties
Susko3
Susko32y ago
or, load the json as ../../my_file.json instead of just my_file.json in your code you could also include the json in the build and set it to be copied to the output directory (not sure what the exact steps are, but I believe I've used the correct terminology)
Rémi
RémiOP2y ago
I'll check that But I've never find anything like that
Susko3
Susko32y ago
I think it's usually right click on the file in Visual Studio
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.

Did you find this page helpful?