如何在 C# 中实现具有子菜单的控制台菜单

时间:2022-11-23
本文介绍了如何在 C# 中实现具有子菜单的控制台菜单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(C#) 我正在开发一个类似于 RedBox 的程序,它将具有客户和经理功能.我只是想在开始实现更多功能之前让所有菜单正常工作,但我遇到了一个我似乎无法理解的错误.我的问题似乎出在 CustomerMenu() 方法和 MainMenu() 方法中.我已经添加了我拥有的所有内容,以便您可以获得完整的图片.感谢任何帮助,因为我仍然有点新,所以感谢任何提示,谢谢.

(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!
"); // The customer menu is brought up if user enters 1
                CustomerMenu();
            }
            if (userChoice == 2)
            {
                Console.WriteLine("Welcome to the manager menu!
"); // 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!  
At VideoMart you are able to rent a variety of movies from many genres such as action, family, horror, etc!");
        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.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.
"); // 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.
"); // 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.
"); // 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.
"); // 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!  
Below is a list of actions that can be performed by customers!");
        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 exit.");
        Console.WriteLine("-----------------------------------------------------------------------------------------------------------");

        string customerChoice2 = Console.ReadLine();
        Console.WriteLine();

        while (!(customerChoice2 == "1" || customerChoice2 == "2" || customerChoice2 == "3" || customerChoice2 == "4") || customerChoice2 == "5") // error checking
        {
        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 exit.");

            customerChoice2 = Console.ReadLine();
        }

        return int.Parse(customerChoice2);
    }
}

推荐答案

使用平面菜单系统

您可以尝试更正并稍微重构一下.

You can try this corrected and a little refactored.

我们创建了一个获取用户选择的方法,因此不再需要重复代码.我们使用 uint 是因为选择是肯定的,并且使用 TryParse 来转换输入的字符串.出错时返回 0,所以这里没问题.

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.

我们还使用 lamda 来打印选择字符串以不重复它们.

Also we use a lamda to print the choices strings to not repeat them.

接下来我们使用 switch 来管理选择,以便代码更干净和可维护.

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.

未来的改进是使用运行这些表的自动菜单管理器创建菜单标题、选项和相关方法的表格.只是稍微复杂一点,但不要太多.这可以通过创建一些集合和一个 MenuManager 类来完成.有了这样的东西,你将拥有一个健壮的系统,代码很少,没有重复.

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();
  }
}

使用自动菜单管理器

这是菜单选项类:

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;
  }
}

这是菜单类:

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;
  }

}

这是菜单管理器类:

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));

现在要做的是:

new MenuManager(root).Run();

这篇关于如何在 C# 中实现具有子菜单的控制台菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

上一篇:使用 SED 在 XML 标签之间提取值 下一篇:使用父级的 DataContext(WPF - 动态菜单命令绑定)

相关文章

最新文章