如何在 dotnet 应用程序中创建导航菜单?

Posted

技术标签:

【中文标题】如何在 dotnet 应用程序中创建导航菜单?【英文标题】:How to create a navigation menu in dotnet application? 【发布时间】:2019-04-17 10:13:45 【问题描述】:

我创建了一个控制台应用程序,它有一个菜单,允许我在菜单项之间导航。我用这个方法处理导航逻辑:

public virtual void updateMenu()

    switch (Console.ReadKey(true).Key)
    
        case ConsoleKey.UpArrow:
            
                if (cursor > 0)
                
                    cursor--;
                    Console.Clear();
                    drawWithHeader();
                
            
            break;
        case ConsoleKey.DownArrow:
            
                if (cursor < (menuItemList.Count - 1))
                
                    cursor++;
                    Console.Clear();
                    drawWithHeader();
                
            
            break;
        case ConsoleKey.Escape:
            
                if (ParentMenu != null)
                

                    hideMenu();
                
            
            break;
        case ConsoleKey.Enter:
            
                Console.Clear();
                drawHeader();
                Console.CursorVisible = true;
                menuItemList[cursor].Action();
                Console.CursorVisible = false;
                Console.Clear();
                drawWithHeader();
            
            break;
        default:
            
                // Unsuported key. Do nothing....
            
            break;
    

here the full class.

现在在 Windows 上一切正常,但是当我在我的 linux 上使用 systemd 运行这个应用程序时,我得到:

未处理的异常:System.InvalidOperationException:当任一应用程序没有控制台或控制台输入已被重定向时,无法读取密钥。试试 Console.Read。

堆栈跟踪显示:

at System.ConsolePal.ReadKey(Boolean intercept)
at System.Console.ReadKey();
at AppRazen.Menu.ConsoleMenu.UpdateMenu();  

经过一番搜索,我发现这个问题与ReadKey()方法不完全compatible with linux有关。而here提出的解决方案在我的情况下根本不起作用,因为用户使用了OminSharp

我也尝试设置ReadKey(false),但这并没有解决问题,我还尝试使用Console.Read() 处理UpdateMenu 中的所有内容,但控制台似乎卡住了。

请注意,仅当我在 linux 主管中运行我的脚本而不是使用 dotnet AppRazen.dll 等默认命令时才会发生此问题

基本上我正在使用systemd 服务运行脚本,如下所示:

[Unit]
Description = Daemon description

[Service]
ExecStart = /usr/bin/dotnet /home/root/Desktop/publish/AppRazen.dll
WorkingDirectory= /home/root/Desktop/publish
Restart = always
RestartSec = 3

[Install]
WantedBy = multi-user.target

老实说,我不知道该如何解决。有人有什么想法吗?

提前致谢。

【问题讨论】:

【参考方案1】:

做你想做的事的简短答案是你根本做不到。

想一想:您正在尝试创建一个交互式程序(用户可以通过键盘与之交互)。但是你也让它成为一个守护进程(一个守护进程在后台运行并且不直接与用户交互)。这是两个相互矛盾的目标。

systemd(或supervisordupstart 或任何系统服务程序)将您的应用程序作为服务运行时,它不会提供与用户交互的方式,因为这些应用程序希望守护进程 - 这意味着用户无法与它们交互。

所以,问问自己你想做什么:你想制作一个交互式程序吗?如果你想制作一个交互式程序,你不能通过主管运行它。通过dotnet /path/to/your.dll 直接运行它。

其他cmets:

ReadKey 可能有问题,但肯定不是您正在干的常见情况,这似乎是 x86_64 上的 Linux。

OmniSharp 是一个用于 IDE/文本编辑器的插件,用于简化开发。它提供自动完成和实时语法高亮。运行应用程序时不涉及。

【讨论】:

以上是关于如何在 dotnet 应用程序中创建导航菜单?的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 中创建带有导航抽屉的汉堡菜单

在导航菜单中的Android应用程序中创建alertdialog以注销

如何使用数据库在 Laravel 中创建动态菜单栏

如何在iphone的子视图页面中创建带有导航返回按钮的导航栏

导航下拉菜单无法正常工作

如何在android中创建自定义导航抽屉