问题
(C#) I am working on a program that is similar to RedBox which will have customer and manager functions. I am just trying to get all the menu's working correctly before I begin implementing more functions, but I am encountering an error that I can not seem to understand. My issue seems to be in the CustomerMenu() method and in the MainMenu() method. I have added all that I have so you can get the full picture. Any help is appreciated as I am still somewhat new so any tips are appreciated, thank you.
MainMenu();
Console.ReadKey();
}
static void MainMenu()
{
int userChoice = MainMenuChoice(); // Reading in the userChoice with the MenuChoice method
if (userChoice == 3) // if user enters 3, the program ends
{
Console.WriteLine("Thank you, Goodbye!");
}
while (userChoice != 3)
{
if (userChoice == 1)
{
Console.WriteLine("Welcome to the customer menu!\n"); // The customer menu is brought up if user enters 1
CustomerMenu();
}
if (userChoice == 2)
{
Console.WriteLine("Welcome to the manager menu!\n"); // The manager menu is brought up if user enters 2
//ManagerMenu();
}
userChoice = MainMenuChoice(); // program ends
if (userChoice == 3)
{
Console.WriteLine("Thank you for visiting VideoMart at University Boulevard, Goodbye!");
}
}
}
static int MainMenuChoice()
{
Console.WriteLine("-----------------------------------------------------------------------------------------------------------"); // introducing the user with the menu
Console.WriteLine("Welcome to VideoMart at University Boulevard! \nAt VideoMart you are able to rent a variety of movies from many genres such as action, family, horror, etc!");
Console.WriteLine("\nPress 1 if you are a customer");
Console.WriteLine("\nPress 2 if you are a manager");
Console.WriteLine("\nPress 3 to Exit");
Console.WriteLine("-----------------------------------------------------------------------------------------------------------");
string choice = Console.ReadLine();
Console.WriteLine();
while (!(choice == "1" || choice == "2" || choice == "3")) // error checking
{
Console.WriteLine("Please try again");
Console.WriteLine("Press 1 if you are a customer");
Console.WriteLine("Press 2 if you are a manager");
Console.WriteLine("Press 3 to Exit");
choice = Console.ReadLine();
}
return int.Parse(choice);
}
}
static void CustomerMenu() {
int customerChoice = CustomerMenuChoice(); // Reading in the customerChoice into the CustomerMenuChoice method
if (customerChoice == 5) // if user enters 5, the program ends
{
Console.WriteLine("Thank you for using VideoMart!");
}
while (customerChoice != 5)
{
if (customerChoice == 1)
{
Console.WriteLine("Press 1 to view movies available to rent.\n"); // this option gives the user the opportunity to view all movies available to rent
//MoviesAvailable();
}
if (customerChoice == 2)
{
Console.WriteLine("Press 2 to rent a movie.\n"); // this option gives the user the opportunity to rent a movie, with email address
//RentMovie();
}
if (customerChoice == 3)
{
Console.WriteLine("Press 3 to view a list of movies you currently have rented.\n"); // this option gives the user the opportunity to view movies a user currently has rented, with email address
//RentMovie();
}
if (customerChoice == 4)
{
Console.WriteLine("Press 4 to return a movie rented.\n"); // this option gives the user the opportunity to return a movie rented
//RentMovie();
}
customerChoice = CustomerMenuChoice();
if (customerChoice == 5)
{
Console.WriteLine("Thank you for visiting VideoMart at University Boulevard, Goodbye!");
}
}
}
static int CustomerMenuChoice()
{
Console.WriteLine("-----------------------------------------------------------------------------------------------------------"); // introducing the user with the menu
Console.WriteLine("Welcome to VideoMart at University Boulevard! \nBelow is a list of actions that can be performed by customers!");
Console.WriteLine("\nPress 1 to view movies available to rent.");
Console.WriteLine("\nPress 2 to rent a movie.");
Console.WriteLine("\nPress 3 to view a list of movies you currently have rented.");
Console.WriteLine("\nPress 4 to return a movie rented.");
Console.WriteLine("\nPress 5 to exit.");
Console.WriteLine("-----------------------------------------------------------------------------------------------------------");
string customerChoice2 = Console.ReadLine();
Console.WriteLine();
while (!(customerChoice2 == "1" || customerChoice2 == "2" || customerChoice2 == "3" || customerChoice2 == "4") || customerChoice2 == "5") // error checking
{
Console.WriteLine("\nPress 1 to view movies available to rent.");
Console.WriteLine("\nPress 2 to rent a movie.");
Console.WriteLine("\nPress 3 to view a list of movies you currently have rented.");
Console.WriteLine("\nPress 4 to return a movie rented.");
Console.WriteLine("\nPress 5 to exit.");
customerChoice2 = Console.ReadLine();
}
return int.Parse(customerChoice2);
}
}
回答1:
Using a flat menu system
You can try this corrected and a little refactored.
We created a method to get the user choice, so repeat code is no more needed. We use uint because choice is positive and TryParse to convert the inputed string. It returns 0 in case of error, so that's fine here.
Also we use a lamda to print the choices strings to not repeat them.
Next we use a switch to manage choice so the code is more clean and maintainable.
The console is cleared between menus and we offer navigation between root and sub menus.
A future improvement is to create tables of menus headers, choices and associated methods... with a auto-menu manager that runs these tables. Just a little more complex but not too much. It can be done by creating some collections and a MenuManager class. With such thing, you will have a robust system with very few code and nothing repeated.
static void Test()
{
MainMenu();
}
static uint GetUserChoice(Action printMenu, int choiceMax)
{
uint choice = 0;
Action getInput = () =>
{
uint.TryParse(Console.ReadLine(), out choice);
};
getInput();
while ( choice < 1 || choice > choiceMax )
{
Console.WriteLine();
Console.WriteLine("Please try again");
printMenu();
getInput();
}
return choice;
}
static void MainMenu()
{
Action printMenu = () =>
{
Console.WriteLine("Press 1 if you are a customer");
Console.WriteLine("Press 2 if you are a manager");
Console.WriteLine("Press 3 to Exit");
};
Console.Clear();
Console.WriteLine("-----------------------------------------------------------------------------------------------------------"); // introducing the user with the menu
Console.WriteLine("Welcome to VideoMart at University Boulevard!");
Console.WriteLine("At VideoMart you are able to rent a variety of movies from many genres such as action, family, horror, etc!");
Console.WriteLine();
printMenu();
Console.WriteLine("-----------------------------------------------------------------------------------------------------------");
uint choice = GetUserChoice(printMenu, 3);
switch ( choice )
{
case 1:
CustomerMenu();
break;
case 2:
//ManagerMenu();
break;
case 3:
Console.WriteLine("Thank you for visiting VideoMart at University Boulevard, Goodbye!");
break;
default:
throw new NotImplementedException();
}
}
static void CustomerMenu()
{
Action printMenu = () =>
{
Console.WriteLine("Press 1 to view movies available to rent.");
Console.WriteLine("Press 2 to rent a movie.");
Console.WriteLine("Press 3 to view a list of movies you currently have rented.");
Console.WriteLine("Press 4 to return a movie rented.");
Console.WriteLine("Press 5 to return to main menu.");
};
Console.Clear();
Console.WriteLine("-----------------------------------------------------------------------------------------------------------"); // introducing the user with the menu
Console.WriteLine("Below is a list of actions that can be performed by customers!");
Console.WriteLine();
printMenu();
Console.WriteLine("-----------------------------------------------------------------------------------------------------------");
Console.WriteLine();
uint choice = GetUserChoice(printMenu, 5);
switch ( choice )
{
case 1:
//MoviesAvailable();
break;
case 2:
//RentMovie();
break;
case 3:
//RentedMovies();
break;
case 4:
//ReturnMovie();
break;
case 5:
MainMenu();
break;
default:
throw new NotImplementedException();
}
}
Using an auto-menu manager
Here is the menu choice class:
public class MenuChoice
{
public string Title { get; private set; }
public Action Action { get; private set; }
public MenuChoice(string title, Action action)
{
Title = title;
Action = action;
}
}
Here is the menu class:
public class Menu
{
private readonly string Separator = new string('-', 100);
private string Header;
private List<MenuChoice> Choices;
private Menu Root;
public Menu(string header, List<MenuChoice> choices, Menu root)
{
Header = header;
Choices = choices;
Root = root;
}
private void Print()
{
for ( int index = 0; index < Choices.Count; index++ )
Console.WriteLine($"Press {index + 1} {Choices[index].Title}");
Console.WriteLine($"Press {Choices.Count + 1} to " +
$"{( Root == null ? "exit" : "go to previous menu" )}");
}
public void Run()
{
Console.Clear();
Console.WriteLine(Separator);
Console.WriteLine(Header);
Console.WriteLine();
Print();
Console.WriteLine(Separator);
uint choice = GetUserChoice();
if ( choice == Choices.Count + 1 )
if ( Root == null )
{
Console.WriteLine("Thank you for visiting VideoMart at University Boulevard, Goodbye!");
return;
}
else
Root.Run();
else
{
var action = Choices[(int)choice - 1].Action;
if ( action != null )
action();
else
{
Console.WriteLine("Not implemented yet, press a key to continue.");
Console.ReadKey();
Run();
}
}
}
uint GetUserChoice()
{
uint choice = 0;
Action getInput = () =>
{
uint.TryParse(Console.ReadLine(), out choice);
};
getInput();
while ( choice < 1 || choice > Choices.Count + 1 )
{
Console.WriteLine();
Console.WriteLine("Please try again");
Print();
getInput();
}
return choice;
}
}
Here is the menu manager class:
public class MenuManager
{
private Menu Root;
public MenuManager(Menu root)
{
Root = root;
}
public void Run()
{
Root.Run();
}
}
Here the menu manager initialization, using methods or another menu instead of null in choices:
var choicesMain = new List<MenuChoice>();
var choicesCustomer = new List<MenuChoice>();
var choicesManager = new List<MenuChoice>();
string headerMain = "Welcome to VideoMart at University Boulevard!" + Environment.NewLine +
"At VideoMart you are able to rent a variety of movies from many genres such as action, family, horror, etc!";
string headerCustomer = "Below is a list of actions that can be performed by customers!";
string headerManager = "Below is a list of actions that can be performed by managers!";
var root = new Menu(headerMain, choicesMain, null);
var menuCustomer = new Menu(headerCustomer, choicesCustomer, root);
var menuManager = new Menu(headerManager, choicesManager, root);
choicesMain.Add(new MenuChoice("if you are a customer", menuCustomer.Run));
choicesMain.Add(new MenuChoice("if you are a manager", menuManager.Run));
choicesCustomer.Add(new MenuChoice("to view movies available to rent.", null));
choicesCustomer.Add(new MenuChoice("to rent a movie.", null));
choicesCustomer.Add(new MenuChoice("to view a list of movies you currently have rented.", null));
choicesCustomer.Add(new MenuChoice("to return a movie rented.", null));
Now all to do is:
new MenuManager(root).Run();
来源:https://stackoverflow.com/questions/58760184/how-to-implement-a-console-menu-having-submenus-in-c-sharp