using System.Text; namespace Debug; public class ModeSwitch { public event Action? Enter; private readonly string[] str = ["退出"]; private int mode = 0; private string title; private string message; public ModeSwitch(string title, string[] a, Action Enter) : this(title, a, Enter, string.Empty) { } public ModeSwitch(string title, string[] a, Action Enter, string message) { this.Enter = Enter; str = a; this.title = title; this.message = message; Run(); } private void Run() { Console.Clear(); PrintCentered("<--- " + title + " --->"); int windowWidth = Console.WindowWidth; for (int i = 0; i < str.Length; i++) { // string paddedString = str[i].PadLeft((windowWidth + str[i].Length) / 2).PadRight(windowWidth); // Console.WriteLine(paddedString); PrintCentered($"{str[i]}"); } // 判断message是不是为空 for (int i = 0; i < windowWidth; i++) { Console.Write('-'); } Console.WriteLine(); PrintCentered("按W/S或↑/↓选择或数字键选择,按Enter确定,按Esc退出"); if (message != string.Empty) { Console.Write(message); } do { var A1 = CalculateActualLength($"{mode}.{str[mode]}"); Console.SetCursorPosition(windowWidth / 2 - A1, mode + 1); Console.Write("<<"); Console.SetCursorPosition(windowWidth / 2 + A1 - 2, mode + 1); Console.Write(">>"); var key = Console.ReadKey(true); Console.SetCursorPosition(windowWidth / 2 - A1, mode + 1); Console.Write(" "); Console.SetCursorPosition(windowWidth / 2 + A1 - 2, mode + 1); Console.Write(" "); // Console.Write(key.Key); if (key.Key >= ConsoleKey.D1 && key.Key <= ConsoleKey.D9) { int v1 = int.Parse(key.KeyChar.ToString()); if (v1 >= 1 && v1 <= str.Length) mode = v1 - 1; } else if (key.Key == ConsoleKey.Escape) { IsEnd(); return; } else switch (key.Key) { case ConsoleKey.UpArrow: case ConsoleKey.W: mode--; break; case ConsoleKey.S: case ConsoleKey.DownArrow: mode++; break; case ConsoleKey.Enter: Enter?.Invoke(mode); return; default: break; } mode = int.Max(0, int.Min(str.Length - 1, mode)); } while (true); } /// /// 确实是否退出 /// private void IsEnd() { Console.Clear(); Console.WriteLine("再次按ESC退出,按回车键继续"); var key = Console.ReadKey(true); if (key.Key == ConsoleKey.Escape) { Console.Clear(); Environment.Exit(0); } else if (key.Key == ConsoleKey.Enter) { Run(); } } private static int CalculateActualLength(string text) { Encoding encoding = Encoding.UTF8; int length = 0; foreach (char c in text) { byte[] bytes = encoding.GetBytes(c.ToString()); if (bytes.Length > 1) // 汉字或宽字符 length += 2; else length += 1; } return length; } public static void New(string title, string[] a, Action Enter, string message) { _ = new ModeSwitch(title, a, Enter, message); } public static void New(string title, string[] a, Action Enter) { _ = new ModeSwitch(title, a, Enter); } static void PrintCentered(string text) { // 获取控制台窗口的宽度 int consoleWidth = Console.WindowWidth; // 计算文本的宽度,对于多字节字符(如中文),可能需要特殊处理 int textLength = GetTextDisplayLength(text); // 计算左右两侧应该填充的空格数 int padding = (consoleWidth - textLength) / 2; if (padding > 0) { // 打印左侧空格 Console.Write(new string(' ', padding)); } // 打印文本 Console.WriteLine(text); } static int GetTextDisplayLength(string text) { // 默认每个字符占一个位置,包括ASCII字符和非ASCII字符(如中文) // return text.Length; // * 如果需要更精确地计算字符宽度(例如考虑全角半角字符的区别),可以使用以下代码: int length = 0; foreach (char c in text) { // 假设所有非ASCII字符都是双宽度字符 length += char.IsHighSurrogate(c) || char.IsLowSurrogate(c) || c > 127 ? 2 : 1; } return length; } }