Grayda
Member
- Joined
- May 20, 2010
- Messages
- 16
- Programming Experience
- 10+
Good afternoon everyone,
While working on my first console app, I had the need to create an interactive menu. There were some solutions about, but most of them required the screen to be cleared with each key press. This wasn't a good solution for me so I came up with my own. You pass it two string arrays -- one for the text to display, one for the values to return and optionally a welcome message to display. The result is a vertical menu that you can use the up / down arrows on to select an item. The screen is never cleared during the process, so you can preserve previously entered text.
Usage:
Example:
Returns:
Output:
The code:
It should be ready to copy and paste into your app. There might be some bugs that I'm not sure about (e.g. titles longer than 40 characters etc.) but this is something you should be able to work with.
It also needs some Try .. Catch statements in there, because if you mismatch the number of text / values items, it'll chuck up an error but my deadline doesn't really give me a whole lot of time for that
Enjoy!
While working on my first console app, I had the need to create an interactive menu. There were some solutions about, but most of them required the screen to be cleared with each key press. This wasn't a good solution for me so I came up with my own. You pass it two string arrays -- one for the text to display, one for the values to return and optionally a welcome message to display. The result is a vertical menu that you can use the up / down arrows on to select an item. The screen is never cleared during the process, so you can preserve previously entered text.
Usage:
VB.NET:
menu(text(), values(), [message])
Example:
VB.NET:
Sub Main()
Dim selection As String
selection = menu({"Option 1", "Option 2", "Option 3", "Option 4", "Option 5"}, {"1", "2", "3", "4", "5"}, "")
Console.WriteLine()
Console.WriteLine("You have selected: " & selection)
Console.ReadKey()
End Sub
Returns:
VB.NET:
The selection as string (1, 2, 3, 4 or 5 in the example above)
Output:
VB.NET:
Please select an option:
>> 1
2
3
4
5
The code:
VB.NET:
Function menu(ByVal text() As String, ByVal values() As String, Optional ByVal welcometext As String = "Choose one of the following:")
' The currently selected item
Dim curIndex As Integer
' For our loop
Dim i As Integer
' The original position of our cursor BEFORE the menu is written
' (This lets us overwrite our menu without having to clear the screen)
Dim t As Integer
t = Console.CursorTop + 1
' Gotos? Bad! But for brevity's sake .. :B
writemenu:
' Re-set our cursor position
Console.CursorTop = t
' Spit out our welcome text, then a blank line for neatness
Console.WriteLine(welcometext)
Console.WriteLine()
' Loop through the values()
For i = 0 To values.Length - 1
' If i = our currently selected item
If i = curIndex Then
' Highlight it
Console.ForegroundColor = ConsoleColor.Black
Console.BackgroundColor = ConsoleColor.Gray
' Put >> in front to denote it's the selected item
Console.Write(">> " & text(i).ToString)
' Reset our console colours
Console.ForegroundColor = ConsoleColor.Gray
Console.BackgroundColor = ConsoleColor.Black
' Pad the rest out with spaces (to cover up any menu artifacts
' that come with mismatched line lengths)
Console.WriteLine(New String(" ", 40))
Else ' If this isn't our selected item, then
' Spit out the text (indented with three spaces)
' then pad the rest with spaces to clean up
Console.WriteLine(" " & text(i).ToString & New String(" ", 40))
End If
Next
' Uh oh, 2 gotos?
selectagain:
' Read one key from the console and return it as the variable called "key"
Dim key As ConsoleKeyInfo = Console.ReadKey(True)
Select Case key.Key.ToString
Case "UpArrow"
' If we have room to move (that is, if we're not at the start
' of the menu)
If curIndex > 0 Then
' Increment the selected index by one.
' When the menu is redrawn, the new item appears to be selected
curIndex -= 1
Else ' If we're at the start of the menu and we're trying to go up
' "Scroll" to the bottom menu option
curIndex = text.Count - 1
End If
Case "DownArrow"
If curIndex < text.Length - 1 Then
curIndex += 1
Else
' Same as before, but if we're at the bottom, go to the top
curIndex = 0
End If
' We've decided
Case "Enter"
' Return the value that corresponds with curIndex
Return values(curIndex)
Case Else ' Otherwise
' Go back, read another key and do it all again
GoTo selectagain
End Select
' Just in case
GoTo writemenu
End Function
It should be ready to copy and paste into your app. There might be some bugs that I'm not sure about (e.g. titles longer than 40 characters etc.) but this is something you should be able to work with.
It also needs some Try .. Catch statements in there, because if you mismatch the number of text / values items, it'll chuck up an error but my deadline doesn't really give me a whole lot of time for that
Enjoy!