2015-11-19 59 views
1
class menu 
{ 
    string[] elements; 
    public menu(string[] ele) { elements = ele; } 
    public menu() : this(new string[3]) { } 
    public void dispMenu(int sel) 
    { 
     Console.Clear(); 
     Console.SetCursorPosition(0, 0); 
     for (int i = 0; i != elements.Length; i++) 
     { 
      if (i != sel) { Console.WriteLine(" " + elements[i]); } 
      else { Console.WriteLine(">" + elements[i] + "<"); }     
     } 
    } 
    public int doMenu() 
    { 
     int selection = 0; 
     do 
     { 
      dispMenu(selection); 
      while (!Console.KeyAvailable) 
      { 

      } 
      if (Console.ReadKey().Key == ConsoleKey.UpArrow) 
      { 
       if (selection == 0) { selection = elements.Length; } 
       else { selection--; } 
      } 
      else if (Console.ReadKey().Key == ConsoleKey.DownArrow) 
      { 
       if (selection == elements.Length) { selection = 0; } 
       else { selection++; } 
      } 
     } while (Console.ReadKey(true).Key != ConsoleKey.Enter); 
     return selection; 
    } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     menu swag = new menu(new string[3] {"Swag", "Money", "yolo"}); 
     Console.WriteLine(swag.doMenu()); 
     Console.Read(); 
    } 
} 

爲什麼這個掛斷?這是一個菜單對象,應該向上和向下箭頭作出響應,並在按下輸入時終止,並返回選擇。運行時它可以工作,但是您必須多次按下該鍵才能註冊。回車鍵也表現這種方式。這爲什麼掛斷?菜單程序

+0

我懷疑這是問題,但是您的代碼頂部有一個無關的「{」(第1行)。 –

+0

不是這個問題,那只是從代碼粘貼到這個論壇 –

回答

1

Console.ReadKey()方法返回用戶按下的下一個字符或功能鍵。您在循環中多次調用此方法,因此第一次調用讀取第一個鍵,第二次調用讀取第二個鍵等等。除非您在正確的時刻點擊正確的密鑰,否則您的代碼無法使用。

另外,documentation states

,即,該線程發出ReadKey方法上的塊,直到一個字符或功能鍵被按下

所以空循環與!Console.KeyAvailable的ReadKey方法等待檢查是沒有必要的。

該代碼可以簡化如下

public int doMenu() { 
    int selection = 0; 
    ConsoleKeyInfo key = null; 

    do { 
     dispMenu(selection); 
     key = Console.ReadKey(); 

     if (key.Key == ConsoleKey.UpArrow) 
     { 
      if (selection == 0) { selection = elements.Length; } 
      else { selection--; } 
     } 
     else if (key.Key == ConsoleKey.DownArrow) 
     { 
      if (selection == elements.Length) { selection = 0; } 
      else { selection++; } 
     } 
    } while (key.Key != ConsoleKey.Enter); 
    return selection; 
} 
1

在進行所有比較之前,將Console.ReadKey()結果分配給一個變量。否則,我相信每次遇到條件時都會嘗試讀取輸入。現在你做了三次,所以第一次你點擊一個鍵時,它只會比較UpArrow的條件,第二次 - 對於DownArrow,第三次 - 僅限於Enter,所以你必須多次敲擊一個鍵直到它被處理。 這樣的事情你doMenu方法:

public int doMenu() 
{ 
    int selection = 0; 
    ConsoleKeyInfo consoleKeyInfo; 
    do 
    { 
     dispMenu(selection); 
     while (!Console.KeyAvailable) 
     { 

     } 
     consoleKeyInfo = Console.ReadKey(); 
     if (consoleKeyInfo.Key == ConsoleKey.UpArrow) 
     { 
      if (selection == 0) { selection = elements.Length; } 
      else { selection--; } 
     } 
     else if (consoleKeyInfo.Key == ConsoleKey.DownArrow) 
     { 
      if (selection == elements.Length) { selection = 0; } 
      else { selection++; } 
     } 
    } while (consoleKeyInfo.Key != ConsoleKey.Enter); 
    return selection; 
} 
0

就像一個到Console.ReadLine()函數,它將停止程序,以接收輸入的每個出現的功能的時間。正如raderick所說,你應該把ReadKey分配給一個變量,所以它只需要一次輸入。