在控制台应用中实现导航菜单

本文关键字:导航 菜单 实现 控制台 应用 | 更新日期: 2023-09-27 18:13:43

我正试图实现复杂的控制台菜单与几个多级子菜单(路径类型菜单)。也许有人建议在我的情况下使用什么设计模式?

顶部菜单示例

* Main Menu *
1. List Virtual Servers
2. List Image Templates
3. Exit

例如选择了1,则出现下一个子菜单

* List Virtual Servers *
1. Virtual server #1
2. Virtual server #2
3. Virtual server #3
4. Return

例如选择了2,则出现下一个子菜单

* Command for Virtual server #2 *
1. Delete
2. Return

我当前的导航代码如下,这只是第一个顶部菜单,不确定如何实现多级路径类型的菜单与完整的导航上下菜单。

static void Main(string[] args)
{
    Console.WriteLine("1. List Virtual Servers" +
       Environment.NewLine + "2. List Image Templates" +
       Environment.NewLine + "3. Exit");
    var input = Console.ReadKey();
    var key = input.KeyChar;
    int value;
    if (int.TryParse(key.ToString(), out value))
    {
        Console.WriteLine();
        RouteChoice(value);
    }
    else
    {
        Console.WriteLine("Invalid Entry.");
    }
    Console.Write("Press any key to exit...");
    Console.ReadKey(false);
    Console.ReadLine();
}
private static void RouteChoice(int menuChoice)
{
    switch (menuChoice)
    {
        case 1:
            GetVirtualServers();
            break;
        case 2:
            GetImageTemplate();
            break;                
        default:
            Console.WriteLine("Invalid Entry!");
            break;
    }
}

在控制台应用中实现导航菜单

我的想法是将菜单项的层次结构建模为树,并在用户浏览菜单时遍历这棵树。从设计模式的角度来看,它将是Composite和Command +一些树遍历的混合。为了做到这一点,我们需要:

  1. 一个基类BaseCommand来模拟菜单中的每个命令。

  2. 一个基类Command派生自BaseCommand,用于菜单项执行一些逻辑-用于树中的叶子。

  3. 一个基类CompositeCommand派生自BaseCommand,用于有子命令的命令。这个类将有Children属性,它将存储类型为BaseCommand的对象。

  4. 每个可以执行某些逻辑的命令,例如虚拟服务器#1应该从命令派生。

  5. 每个有子命令的命令,例如List Virtual Servers应该从CompositeCommand派生。

  6. 在程序的开始,你应该创建一个命令树。在您的例子中,在这棵树的根,我们将找到Main MenuMain MenuChildren属性将包含对List Virtual ServersList Image TemplatesExit等命令的引用。

  7. 这个解决方案的最后一部分是管理器。管理器是一个类,它必须跟踪我们在树中的位置。当管理器接收到来自用户的输入时,他可以做三件事:如果当前命令是叶子命令,则执行当前命令;如果用户选择返回,则移动到当前命令的父命令;如果当前命令有子命令,则移动到当前命令的子命令。

我已经写了一个控制台菜单,它可能是一个有用的起点。

CMenu是一个轻量级的、简单的框架,用于在。net中构建控制台菜单。与手动提示用户输入和解析不同,您可以以简短、结构化和全面的方式定义命令,并让CMenu处理其余部分。

CMenu的目标是低开销-简单的东西应该很容易实现。如果你不使用一个特性,你就不需要了解它。

同时支持复杂场景。大型菜单可以很容易地分成几个类。背景自我配置。你不必担心大菜单中涉及的所有烦人的细节,它会正常工作。

最重要的是,它使用起来非常简单和快速。命令可以缩写,智能解析器甚至支持部分匹配。集成了帮助命令

在编写时并没有考虑到这种编号的操作风格,但是它可以被模拟,并且如果将命令命名为"1,应该可以完美地工作。"foo"; 2。bar"等。

继承系统非常简单(只是从CMenuItem和覆盖Execute派生),或者如果你想,你甚至可以使用lambdas代替。

var menu = new CMenu ();
menu.Add ("1. foo", s => Console.WriteLine ("Foo!"));
menu.Add ("2. bar", s => Console.WriteLine ("Bar!"));
menu.Run ();

菜单树得到了很好的支持,参见本页的示例。举个例子(还有其他创建分层菜单的方法):

var m = new CMenu () {
    new CMenuItem ("1") {
        new CMenuItem ("1", s => Console.WriteLine ("1-1")),
        new CMenuItem ("2", s => Console.WriteLine ("1-2")),
    },
    new CMenuItem ("2") {
        new CMenuItem ("1", s => Console.WriteLine ("2-1")),
        new CMenuItem ("2", s => Console.WriteLine ("2-2")),
    },
};

更新:通过单个数字键选择将在下一个版本(0.8)中原生包含。