Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在控制台应用程序中实现导航菜单_C#_Design Patterns_Console Application - Fatal编程技术网

C# 在控制台应用程序中实现导航菜单

C# 在控制台应用程序中实现导航菜单,c#,design-patterns,console-application,C#,Design Patterns,Console Application,我试图实现复杂的控制台菜单与多个多级子菜单(路径类型菜单)。也许有人建议在我的情况下使用什么设计模式 顶部菜单示例 如果选择了示例1,则会出现下一个子菜单 如果选择了示例2,则会出现下一个子菜单 我当前的导航代码如下,这只是第一个顶部菜单,不确定如何实现多级路径类型菜单,通过菜单上下全导航 static void Main(string[] args) { Console.WriteLine("1. List Virtual Servers" + Environment.

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

顶部菜单示例

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

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

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

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

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

  • 用于对菜单中的每个命令建模的基类BaseCommand

  • 从BaseCommand派生的基类命令,用于对树中的叶执行某些逻辑的菜单项

  • 一个基类CompositeCommand,派生自带子命令的BaseCommand。此类将具有子属性,该属性将存储BaseCommand类型的对象

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

  • 每个包含子命令(例如列表虚拟服务器)的命令都应派生自CompositeCommand

  • 在程序开始时,您应该创建一个命令树。在您的情况下,在这棵树的根中,我们将找到主菜单。主菜单的Children属性将包含对列表虚拟服务器、列表图像模板、退出等命令的引用

  • 此解决方案的最后一部分是管理器。经理是一个必须跟踪我们在树中的位置的类。当管理器收到用户的输入时,他可以做3件事:如果当前命令是叶子,则执行该命令;如果用户选择Return,则移动到当前命令的父命令;如果当前命令有叶子,则移动到当前命令的子命令


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

  • 用于对菜单中的每个命令建模的基类BaseCommand

  • 从BaseCommand派生的基类命令,用于对树中的叶执行某些逻辑的菜单项

  • 一个基类CompositeCommand,派生自带子命令的BaseCommand。此类将具有子属性,该属性将存储BaseCommand类型的对象

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

  • 每个包含子命令(例如列表虚拟服务器)的命令都应派生自CompositeCommand

  • 在程序开始时,您应该创建一个命令树。在您的情况下,在这棵树的根中,我们将找到主菜单。主菜单的Children属性将包含对列表虚拟服务器、列表图像模板、退出等命令的引用

  • 此解决方案的最后一部分是管理器。经理是一个必须跟踪我们在树中的位置的类。当管理器收到用户的输入时,他可以做3件事:如果当前命令是叶子,则执行该命令;如果用户选择Return,则移动到当前命令的父命令;如果当前命令有叶子,则移动到当前命令的子命令

  • 我写了一些可能对你有用的文章作为起点

    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 ();
    
    菜单树得到了很好的支持,请参见。例如(创建分层菜单还有其他方法):

    更新:在下一个版本(0.8)中,通过单数字键进行的选择将包含在本机中。

    我已经编写了这篇文章,可以作为您的起点

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

    CMenu的目标是低开销——简单的东西应该易于实现。如果你不使用某个特性,你就不需要知道它的任何信息

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

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

    它并没有考虑到这种编号的操作风格,但它可以
    * 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;
        }
    }
    
    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")),
        },
    };