-
Feb 2nd, 2024, 04:12 PM
#1
Console Application - Menu
I had a situation where I needed to provide users with a list of values and they had to select one. At first, I just had it loop over every item and prefix it with it's ordinal index. This worked, but I wanted to provide a more interactive way for the user to select an option, so I decided to whip something up that will allow the user to use their arrow keys to cycle through the items and select an option.
This is the code:
Code:
Private Function GetSelectedMenu(menuItems As IEnumerable(Of String), Optional selectedIndex As Integer = 0) As Integer
If (Not menuItems.Any()) Then
Throw New ArgumentOutOfRangeException(NameOf(menuItems))
End If
If (selectedIndex < 0 OrElse selectedIndex > menuItems.Count - 1) Then
Throw New ArgumentOutOfRangeException(NameOf(selectedIndex))
End If
Console.Clear()
DisplayMenu(menuItems, selectedIndex)
Dim key = Console.ReadKey()
Select Case key.Key
Case ConsoleKey.UpArrow
If selectedIndex > 0 Then
selectedIndex -= 1
End If
Case ConsoleKey.DownArrow
If (selectedIndex < menuItems.Count - 1) Then
selectedIndex += 1
End If
Case ConsoleKey.Enter
Return selectedIndex
End Select
Return GetSelectedMenu(menuItems, selectedIndex)
End Function
Private Sub DisplayMenu(menuItems As IEnumerable(Of String), selectedIndex As Integer)
If (Not menuItems.Any()) Then
Throw New ArgumentOutOfRangeException(NameOf(menuItems))
End If
If (selectedIndex < 0 OrElse selectedIndex > menuItems.Count - 1) Then
Throw New ArgumentOutOfRangeException(NameOf(selectedIndex))
End If
For menuItemIndex = 0 To menuItems.Count - 1
If menuItemIndex = selectedIndex Then
Console.ForegroundColor = ConsoleColor.Green
End If
Dim menuItem = menuItems(menuItemIndex)
Console.WriteLine(menuItem)
Console.ResetColor()
Next
End Sub
And this is the implementation:
Code:
Console.CursorVisible = False
Dim menuItems = Enumerable.Range(1, 5).Select(Function(i) $"Menu {i}")
Dim selectedMenuItem = GetSelectedMenu(menuItems)
Console.Clear()
Console.WriteLine("You selected {0}", selectedMenuItem)
Console.ReadLine()
The basic idea is that you essentially end up an in a recursive loop where it will do the following:
- Clear the console
- Loop over the menu items
- Print the currently iterated item
- If the currently iterated item is the currently "selected" item, change the forecolor to green
- Call ReadKey
- If the key is enter, then return the selected index value.
- Otherwise...
- If the key is the up arrow, try to decrement the selected index value
- If the key is the down arrow, try to increment the selected index value
- Regardless of the input, recursively call the method by returning the method's value
Something that I didn't include that might be useful is a "title" argument to the GetSelectedMenu's event signature that will display text at the top of the console before all the menu items.
Last edited by dday9; Feb 2nd, 2024 at 10:46 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|