C#控制台程序选择菜单回车后无显示,仅上下箭头可触发刷新问题
C#控制台菜单回车后不刷新问题解决
问题描述
我正在开发一款用于缓解无聊的C#控制台程序,计划在学校电脑上展示给大家使用。程序的交互式菜单参考了Stack Overflow上的帖子实现,但存在一个问题:选中选项按下回车键后,屏幕会清空,只有按下上或下箭头键时菜单才会重新显示。
问题原因分析
当前代码中,按下回车后会调用对应的XXXPageLink()方法,这些方法只执行了Console.Clear()和重新赋值全局options列表,但没有调用WriteMenu()方法重新绘制菜单。所以屏幕清空后处于空白状态,直到按下上下箭头触发WriteMenu()才会重新显示菜单内容。
另外,当前实现中每个XXXPageLink()都重复创建了几乎完全一样的options列表,代码冗余度很高,也增加了维护成本。
解决方案
快速修复方案
直接在每个XXXPageLink()方法的末尾添加菜单重绘逻辑,调用WriteMenu()显示更新后的菜单:
修改后的各个页面跳转方法示例:
static void HomePageLink() { Console.Clear(); options = new List<Option> { new Option("> 🏡 Home ", () => HomePageLink()), new Option(" 📩 Request ", () => RequestPageLink()), new Option(" ⚙️ Configure ", () => ConfigurePageLink()), new Option(" 💫 Updates ", () => UpdatePageLink()), new Option(" ❌ Exit ", () => Environment.Exit(0)), }; // 新增:重绘菜单,找到当前标记为选中的选项(以>开头) var selectedOption = options.First(o => o.Name.StartsWith(">")); WriteMenu(options, selectedOption); } static void RequestPageLink() { Console.Clear(); options = new List<Option> { new Option(" 🏡 Home ", () => HomePageLink()), new Option("> 📩 Request ", () => RequestPageLink()), new Option(" ⚙️ Configure ", () => ConfigurePageLink()), new Option(" 💫 Updates ", () => UpdatePageLink()), new Option(" ❌ Exit ", () => Environment.Exit(0)), }; var selectedOption = options.First(o => o.Name.StartsWith(">")); WriteMenu(options, selectedOption); } // 其余UpdatePageLink、ConfigurePageLink方法做同样修改
优雅重构方案
重构代码,避免重复创建options列表,通过维护选中索引来标记当前选中项,减少冗余:
using System.Text; using System; using System.Collections.Generic; using System.Linq; namespace Awesome_C__Project { internal class Program { // 只初始化一次菜单选项,存储选项名称和对应的动作 private static readonly List<(string Name, Action Action)> _menuItems = new List<(string, Action)> { ("🏡 Home", () => ShowPage("🏡 Home")), ("📩 Request", () => ShowPage("📩 Request")), ("⚙️ Configure", () => ShowPage("⚙️ Configure")), ("💫 Updates", () => ShowPage("💫 Updates")), ("❌ Exit", () => Environment.Exit(0)), }; // 当前选中的菜单索引 private static int _selectedIndex = 0; static void Main(string[] args) { Console.OutputEncoding = Encoding.UTF8; WriteMenu(); ConsoleKeyInfo keyinfo; do { keyinfo = Console.ReadKey(true); // true参数避免按键显示在控制台 switch (keyinfo.Key) { case ConsoleKey.DownArrow: if (_selectedIndex + 1 < _menuItems.Count) { _selectedIndex++; WriteMenu(); } break; case ConsoleKey.UpArrow: if (_selectedIndex - 1 >= 0) { _selectedIndex--; WriteMenu(); } break; case ConsoleKey.Enter: _menuItems[_selectedIndex].Action.Invoke(); break; } } while (keyinfo.Key != ConsoleKey.X); } // 显示页面(这里可以扩展每个页面的具体逻辑) static void ShowPage(string pageName) { Console.Clear(); // 这里可以添加页面的具体内容,比如: Console.WriteLine($"当前页面:{pageName}"); Console.WriteLine("\n按任意键返回菜单..."); Console.ReadKey(true); // 返回菜单后重新绘制 WriteMenu(); } static void WriteMenu() { Console.Clear(); Console.WriteLine("=== 无聊缓解工具 ==="); Console.WriteLine(); for (int i = 0; i < _menuItems.Count; i++) { var item = _menuItems[i]; if (i == _selectedIndex) { // 选中项高亮背景 Console.Write("\u001b[48;2;50;50;50m"); Console.WriteLine($"> {item.Name}"); } else { Console.Write("\u001b[48;2;12;12;12m"); Console.WriteLine($" {item.Name}"); } // 重置背景色 Console.Write("\u001b[0m"); } Console.WriteLine("\n使用上下箭头选择,按回车确认"); } } }
这个重构版本的优势:
- 菜单选项只初始化一次,避免重复代码
- 通过
_selectedIndex维护选中状态,无需修改选项名称 - 页面逻辑和菜单逻辑分离,更容易扩展每个页面的功能
- 添加了返回菜单的逻辑,用户体验更完整
内容的提问来源于stack exchange,提问作者01maxzie
相关产品推荐
相关产品推荐

