在控制台应用中实现导航菜单
本文关键字:导航 菜单 实现 控制台 应用 | 更新日期: 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 +一些树遍历的混合。为了做到这一点,我们需要:
-
一个基类BaseCommand来模拟菜单中的每个命令。
-
一个基类Command派生自BaseCommand,用于菜单项执行一些逻辑-用于树中的叶子。
-
一个基类CompositeCommand派生自BaseCommand,用于有子命令的命令。这个类将有Children属性,它将存储类型为BaseCommand的对象。
-
每个可以执行某些逻辑的命令,例如虚拟服务器#1应该从命令派生。
-
每个有子命令的命令,例如List Virtual Servers应该从CompositeCommand派生。
-
在程序的开始,你应该创建一个命令树。在您的例子中,在这棵树的根,我们将找到Main Menu。Main Menu的Children属性将包含对List Virtual Servers、List Image Templates、Exit等命令的引用。
-
这个解决方案的最后一部分是管理器。管理器是一个类,它必须跟踪我们在树中的位置。当管理器接收到来自用户的输入时,他可以做三件事:如果当前命令是叶子命令,则执行当前命令;如果用户选择返回,则移动到当前命令的父命令;如果当前命令有子命令,则移动到当前命令的子命令。
我已经写了一个控制台菜单,它可能是一个有用的起点。
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)中原生包含。