首页 > 解决方案 > 控制台上的 C# 菜单和子菜单 - 菜单返回问题

问题描述

我是编程新手,我正在尝试创建一个包含子菜单的菜单。主菜单具有所有要进行的选项,而子菜单具有插入的每个选项的 CRUD。

但是,我已经完成的子菜单(动物)在通过 id 方法进行可视化时都不起作用,并且对于子菜单的以下 crud 方法也是如此。此外,当子菜单完成其任务时,它应该返回初始子菜单选项,允许按零返回主菜单。尽管我尝试以不同的方式做事,但这并没有发生。我不确定是switch语句错误还是方法调用。

对不起,如果代码比平时大一点:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace menu
{
    class Program
    {
        public static int id = 1;
        enum animalHeader { id, name, client_name, type_animal };
        enum clientHeader { id, name, client_surname, adrress };
        static void Main(string[] args)
        {
            string[,] animal = new string[20, 4];
            string[,] client = new string[20, 6];

            do { MenuOptions(animal); } while (true);

        }
        static void MenuOptions(string[,] animal)
        {
            int userChoice;

            do
            {
                Console.Clear();
                Console.WriteLine("\nChoose one of the following options:\n");

                Console.WriteLine("[ 1 ] Animals");
                Console.WriteLine("[ 2 ] Clients");
                Console.WriteLine("[ 0 ] Quit application\n");

            } while (!int.TryParse(Console.ReadLine(), out userChoice) || userChoice < 0 || userChoice > 2);

            Console.Clear();

            switch (userChoice)
            {
                case 1:
                    menuAnimal(animal);
                    menuReturn(animal);
                    break;
                case 2:
                    //menuClient(client);
                    mainMenu();
                    break;
                case 0:
                    Environment.Exit(0);
                    break;
                default:
                    Console.WriteLine("Try again!!");
                    break;
            }
        }
        static void menuAnimal(string[,] animal)
        {
            int optAnimal;

            do
            {
                Console.Clear();
                Console.WriteLine("\nInsert one of the following options:\n");

                Console.WriteLine("[ 1 ] Insert animal");
                Console.WriteLine("[ 2 ] See animal");
                Console.WriteLine("[ 3 ] Alter animal");
                Console.WriteLine("[ 4 ] Erase animal");
                Console.WriteLine("[ 5 ] List animals");
                Console.WriteLine("[ 0 ] Return to main menu\n");

            } while (!int.TryParse(Console.ReadLine(), out optAnimal) || optAnimal < 0 || optAnimal > 5);

            Console.Clear();

            switch (optAnimal)
            {
                case 1:
                    insertData(animal);
                    menuReturn(animal);
                    break;
                case 2:
                    visualizeByid(animal);
                    menuReturn(animal);
                    break;
                case 3:
                    updateById(animal);
                    menuReturn(animal);
                    break;
                case 4:
                    deleteByid(animal);
                    menuReturn(animal);
                    break;
                case 5:
                    listData(animal);
                    menuReturn(animal);
                    break;

            }
        }
        static void mainMenu()
        {
            Console.Clear();
            Console.ReadKey();
        }

        static void menuReturn(string[,] animal)
        {
            Console.Clear();

            do { menuAnimal(animal); } while (true);

        }

        static int generateId()
        {
            return id++;
        }
        static int getInsertIndex(string[,] matrix)
        {
            for (int j = 0; j < matrix.GetLength(0) - 1; j++)
            {
                if (string.IsNullOrEmpty(matrix[j, 0])) return j;
            }

            return -1;
        }
        static void insertData(string[,] matrix)
        {
            int id = generateId();
            int n = getInsertIndex(matrix);

            matrix[n, 0] = Convert.ToString(id);

            for (int j = 1; j < matrix.GetLength(1); j++)
            {
                do
                {
                    Console.Write($"Insert {Enum.GetName(typeof(animalHeader), j)}: ");
                    matrix[n, j] = Console.ReadLine();
                } while (String.IsNullOrEmpty(matrix[n, j]));
            }
        }
        static int searchId(string[,] matrix)
        {
            int choosenId, index = -1;

            do
            {
                Console.Write("Insert ID to continue: ");

            } while (!int.TryParse(Console.ReadLine(), out choosenId));


            for (int i = 0; i < matrix.GetLength(0); i++)
            {
                if (Convert.ToString(choosenId) == matrix[i, 0])
                {
                    index = i;
                }
            }

            return index;
        }
        static void visualizeByid(string[,] matrix)
        {
            int pos = searchId(matrix);

            if (pos != -1)
            {
                for (int i = pos; i < pos + 1; i++)
                {
                    for (int j = 0; j < matrix.GetLength(1); j++)
                    {
                        Console.Write($"{matrix[i, j]}\t");
                    }
                    Console.WriteLine();
                }
            }
            else { Console.WriteLine("Wrong Id"); }
        }
        static void updateById(string[,] matrix)
        {
            int pos = searchId(matrix);
            if (pos != -1)
            {
                for (int i = pos; i < pos + 1; i++)
                {
                    for (int j = 1; j < matrix.GetLength(1); j++)
                    {
                        Console.Write($"Insert {Enum.GetName(typeof(animalHeader), j)}:  ");
                        matrix[i, j] = Console.ReadLine();
                    }
                    Console.WriteLine();
                }
            }
            else { Console.WriteLine("Id does not exist"); }
        }
        static void deleteByid(string[,] matrix)
        {
            int pos = searchId(matrix);
            if (pos != -1)
            {
                for (int i = pos; i < pos + 1; i++)
                {
                    for (int j = 0; j < matrix.GetLength(1); j++)
                    {
                        matrix[i, j] = null;
                    }
                }
            }
            else { Console.WriteLine("Id does not exist"); }
        }
        static void listData(string[,] matrix)
        {
            for (int i = 0; i < matrix.GetLength(0); i++)
            {
                for (int j = 0; j < matrix.GetLength(1); j++)
                {
                    Console.Write($"\t{matrix[i, j]}\t");
                }
                Console.WriteLine("\n\t");

            }
        }
    }
}

标签: c#methodsmenu

解决方案


我能发现的第一个问题是menuAnimal方法。检查输入 0 时会发生什么,例如使用调试器单步执行代码。

当用户输入 0 时,第一个do-while条件通过(因为 0 是一个数字,并且不小于 0 且不大于 5),但是在下面的switch语句中你没有casefor 0,所以方法停止执行并重新绘制,因为执行继续menuReturn(animal);MenuOptions.

这里的下一个主要问题是menuReturn方法。请注意,一旦您使用此方法,您将永远无法“逃脱”。无论发生什么,它都会重新绘制动物菜单,并while(true)确保它会无限期地发生。因为里面没有任何break条件,它会一直持续下去。

不同的方法

我将在这里建议一种不同的方法,尽管您有很多选择,因此您可以自由使用适合您的不同解决方案。

首先摆脱该menuReturn方法并将此“菜单输出循环”放在菜单方法本身中。在伪代码中,这将是:

static void MenuMethod()
{
   while (true)
   {
      userInput = read user input for example using do..while as in original code   

      goBack = false
      switch (userInput)
      {
         case optionA: 
           doSomething();
           goBack = true; //set go back to true if you want go up a level
           break;
         case optionSubmenu:
           submenu(); //go to a submenu, which will start its own loop
           //after submenu is closed (goBack = true), execution will return to this level
           break;
      }
      if (goBack) return; //end execution of this menu
   }
}

因此,在您的情况下,它可能看起来像这样:

static void MenuOptions(string[,] animal)
{
    while (true)
    { 
        int userChoice;

        do
        {
            Console.Clear();
            Console.WriteLine("\nChoose one of the following options:\n");

            Console.WriteLine("[ 1 ] Animals");
            Console.WriteLine("[ 2 ] Clients");
            Console.WriteLine("[ 0 ] Quit application\n");

        } while (!int.TryParse(Console.ReadLine(), out userChoice) || userChoice < 0 || userChoice > 2);

        Console.Clear();

        switch (userChoice)
        {
            case 1:
                menuAnimal(animal);
                break;
            case 2:
                //menuClient(client);
                break;
            case 0:
                Environment.Exit(0);
                break;
            default:
                Console.WriteLine("Try again!!");
                break;
        }
    }
}

动物菜单也类似:

static void MenuAnimal(string[,] animal)
{
    while ( true )
    {
        int optAnimal;

        do
        {
            Console.Clear();
            Console.WriteLine("\nInsert one of the following options:\n");

            Console.WriteLine("[ 1 ] Insert animal");
            Console.WriteLine("[ 2 ] See animal");
            Console.WriteLine("[ 3 ] Alter animal");
            Console.WriteLine("[ 4 ] Erase animal");
            Console.WriteLine("[ 5 ] List animals");
            Console.WriteLine("[ 0 ] Return to main menu\n");

        } while (!int.TryParse(Console.ReadLine(), out optAnimal) || optAnimal < 0 || optAnimal > 5);

        Console.Clear();
        bool goBack = false;
        switch (optAnimal)
        {
            case 1:
                insertData(animal);
                break;
            case 2:
                visualizeByid(animal);
                break;
            case 3:
                updateById(animal);
                break;
            case 4:
                deleteByid(animal);
                break;
            case 5:
                listData(animal);
                break;    
        }
        if ( goBack ) return;
    }
}

推荐阅读