如何在c#中改进我的菜单(控制台)

时间:2016-10-25 16:17:47

标签: c# menu

我在控制台中创建了一个带子菜单的菜单。一切正常,但我想知道是否不可能改进我的程序结构。为了简化它并使其更通用。

class MainClass
{
    public static void Main(string[] args)
    {
        MainMenu();
    }

    public static void MainMenu()
    {
        Console.WriteLine("Main Menu");
        Console.WriteLine("--------------------");
        Console.WriteLine("[1] Show activities");
        Console.WriteLine("[2] Show teachers");
        Console.WriteLine("[3] Show students");
        Console.WriteLine("[4] Exit the program");
        Console.WriteLine("--------------------\n");
        Console.WriteLine("Please select an option from 1-4\n");

        string choice = Console.ReadLine();
        int number;
        bool result = Int32.TryParse(choice, out number);
        if (result)
        {
            Console.Clear();
            SubMenu(number);
        }
        else
        {
            Console.WriteLine("Incorrect choice");
        }
    }

    public static void SubMenu(int mainMenuChoice)
    {
        switch (mainMenuChoice)
        {
            case 1:
                Console.WriteLine("Activities");
                Console.WriteLine("[1] Show all activities");
                Console.WriteLine("[2] Find a activity by his code");
                Console.WriteLine("[3] Return Main Menu");
                Console.WriteLine("[4] Exit the program");
                Console.WriteLine("--------------------\n");
                Console.WriteLine("Please select an option from 1-4\n");
                break;

            case 2:
                Console.WriteLine("Teachers");
                Console.WriteLine("[1] Show all teachers");
                Console.WriteLine("[2] Find a teacher by his matricule");
                Console.WriteLine("[3] Return Main Menu");
                Console.WriteLine("[4] Exit the program");
                Console.WriteLine("--------------------\n");
                Console.WriteLine("Please select an option from 1-4\n");
                break;

            case 3:
                Console.WriteLine("Students");
                Console.WriteLine("[1] Show all students");
                Console.WriteLine("[2] Find a student by his matricule");
                Console.WriteLine("[3] Return Main Menu");
                Console.WriteLine("[4] Exit the program");
                Console.WriteLine("--------------------\n");
                Console.WriteLine("Please select an option from 1-4\n");
                break;

            case 4:
                Environment.Exit(0);
                break;
        }
        string choice = Console.ReadLine();
        int number;
        bool result = Int32.TryParse(choice, out number);
        if (result)
        {
            Action(mainMenuChoice, number);
        }
        else
        {
            Console.WriteLine("Incorrect choice");
        }
    }
    public static void Action(int menu, int choice)
    {
        switch (menu)
        {
            case 1:
                switch (choice)
                {
                    case 1:
                        // Do Stuff
                        break;

                    case 2:
                        // Do Stuff
                        break;

                    case 3:
                        Console.Clear();
                        MainMenu();
                        break;

                    case 4:
                        Environment.Exit(0);
                        break;
                }
                break;

            case 2:
                switch (choice)
                {
                    case 1:
                        // Do Stuff
                        break;

                    case 2:
                        // Do Stuff
                        break;

                    case 3:
                        Console.Clear();
                        MainMenu();
                        break;

                    case 4:
                        Environment.Exit(0);
                        break;
                }
                break;

            case 3:
                switch (choice)
                {
                    case 1:
                        // Do Stuff
                        break;

                    case 2:
                        // Do Stuff
                        break;

                    case 3:
                        Console.Clear();
                        MainMenu();
                        break;

                    case 4:
                        Environment.Exit(0);
                        break;
                }
                break;
        }
    }
}

目前如果我必须添加一个子菜单,我必须在MainMenu()函数中添加一行,我必须在SubMenu()函数中添加一个案例,并且在Action中有多个选项( )。 只有一个子菜单可以,但是如果我必须添加十几个子菜单,很快就会变得无法管理。 我应该经历一个或多个班级,但我在结构上迷失了。

2 个答案:

答案 0 :(得分:1)

我迅速做了一些事情,以展示解决问题的方法。我评论了大部分代码,但询问是否有任何不清楚的地方。对我来说,主要的优点是你可以将菜单作为对象在一个地方声明。在我的代码中,我在Main方法中明确地完成了这个,但您可以轻松编写工厂方法来为您生成菜单。

class Program
{
    //represents a line/option in a menu
    class MenuItem
    {
        // displayed in the menu
        public string Text { get; set; }

        //is there a sub menu
        public bool HasSubMenu { get; set; }

        // if there's a submenu, what's its id
        public int? SubMenuId { get; set; }

        //if there isn't a sub menu, what should we do
        public Action Action { get; set; }
    }

    //represents one menu i.e. a collection of options
    class Menu
    {
        public Menu()
        {
            MenuItems = new List<MenuItem>();
        }

        public int MenuId { get; set; }
        public List<MenuItem> MenuItems { get; set; }
        public string Title { get; set; }

        public void PrintToConsole()
        {
            foreach (MenuItem item in MenuItems)
            {
                Console.WriteLine(MenuItems.IndexOf(item) + " : " + item.Text);
            }
        }
    }

    //represents all the menus
    class MenuCollection
    {
        public MenuCollection()
        {
            Menus = new List<Menu>();
        }

        public List<Menu> Menus { get; set; }

        public void ShowMenu(int id)
        {
            //get the menu we want to display and call its PrintToConsole method
            var currentMenu = Menus.Where(m => m.MenuId == id).Single();
            currentMenu.PrintToConsole();

            //wait for user input
            string choice = Console.ReadLine();
            int choiceIndex;

            //once we have the users selection make sure its an integer and in range of our menu options
            //if not then show an error message and re-display the menu
            if (!int.TryParse(choice, out choiceIndex) || currentMenu.MenuItems.Count < choiceIndex || choiceIndex < 0)
            {
                Console.Clear();
                Console.WriteLine("Invalid selection - try again");
                ShowMenu(id);
            }
            else
            {
                // if the selection is good, then retrieve the corresponding menu item
                var menuItemSelected = currentMenu.MenuItems[choiceIndex];

                // if there's a sub menu then display it
                if (menuItemSelected.HasSubMenu)
                {
                    Console.Clear();
                    ShowMenu(menuItemSelected.SubMenuId.Value);
                }
                // otherwise perform whatever action we need
                else
                {
                    menuItemSelected.Action();
                }
            }
        }
    }

    static void Main(string[] args)
    {
        // build a collection of menus
        // can have as deep a structure as you like
        // give each menu a unique integer MenuId
        // link to other menus by setting HasSubMenu to true, and the SubMenuId to the MenuId of the menu you wish to link to
        // or, set HasSubMenu to false, and have an Action performed when the menuitem is selected
        MenuCollection collection = new MenuCollection()
        {
            Menus =
            {
                new Menu()
                {
                    MenuId = 1,
                    MenuItems =
                    {
                        new MenuItem()
                        {
                            Text = "Go to sub menu",
                            HasSubMenu = true,
                            SubMenuId = 2
                        },
                        new MenuItem()
                        {
                            Text = "Print Action",
                            HasSubMenu = false,
                            Action = () => 
                            {
                                 Console.WriteLine("I printed from an action");
                            }
                        }
                    }
                },
                new Menu()
                {
                    MenuId = 2,
                    MenuItems =
                    {
                        new MenuItem()
                        {
                            Text = "Sub menu option 1",
                            HasSubMenu = false,
                            Action = () => 
                            {
                                Console.WriteLine("Printed from a sub menu");
                            }
                        },
                        new MenuItem()
                        {
                            Text = "Back to the top menu",
                            HasSubMenu = true,
                            SubMenuId = 1
                        }
                    }
                }
            }
        };

        collection.ShowMenu(1);
        Console.ReadLine();
    }
}

答案 1 :(得分:0)

我最近一直在制作许多小型CLI工具,我只是充实了活动,但这里是我通常喜欢采用大量分支菜单/逻辑的方法的一个例子:

class Program
{

    static T GetChoice<T>(List<Tuple<string, T>> choices)
    {
        var i = 1;
        choices.ForEach(x => Console.WriteLine($"[{i++}]: {x.Item1}"));
        var choiceIndex = int.Parse(Console.ReadLine());
        return choices[choiceIndex - 1].Item2;
    }

    static void Main(string[] args)
    {
        Console.WriteLine("Main Menu: ");
        var choices = new List<Tuple<string, Action>>()
        {
            new Tuple<string, Action>("Show Activities", ShowActivities),
            new Tuple<string, Action>("Show Teachers", ShowTeachers),
            new Tuple<string, Action>("Show Students", ShowStudents),
            new Tuple<string, Action>("Exit", Exit),
        };

        GetChoice(choices)();
    }

    static void ShowActivities()
    {
        Console.WriteLine("Activities: ");
        var choices = new List<Tuple<string, Action>>()
        {
            new Tuple<string, Action>("Show all activities", ShowAllActivities),
            new Tuple<string, Action>("Find activity by code", FindActivityByCode),
            new Tuple<string, Action>("Return to main menu", () => { Main(null); }),
            new Tuple<string, Action>("Exit the program", Exit),
        };

        GetChoice(choices)();
    }

    static void ShowTeachers()
    {
        Console.WriteLine("Teachers: ");
        var choices = new List<Tuple<string, Action>>();
    }

    static void ShowStudents()
    {
        Console.WriteLine("Students: ");
        var choices = new List<Tuple<string, Action>>();
    }

    static void ShowAllActivities()
    {
        //Do stuff
    }

    static void FindActivityByCode()
    {
        //Do stuff
    }

    static void ReturnToMainMenu()
    {
        //Do stuff
    }

    static void Exit()
    {
        Environment.Exit(0);
    }
}