【问题标题】:Making a box menu. How do I color/highlight the selection?制作一个盒子菜单。如何为选择着色/突出显示?
【发布时间】:2020-10-30 02:01:43
【问题描述】:

所以我拼凑了一个包含标题和可供选择的选项的菜单。选择一个项目是通过使用箭头键完成的。我希望突出显示选定的项目,以便您知道当前正在选择哪个项目。我是 PowerShell 的新手,并且熟悉如何使用 write-host 更改颜色,但在此示例中我一无所知。我认为我需要将颜色选项注入的有问题的行是以 $Width 开头的行。我真的很感激一些见解!这是我开始添加实际代码之前的最后一个小问题!


    Function Create-Menu (){
    
    Param(
        [Parameter(Mandatory=$True)][String]$MenuTitle,
        [Parameter(Mandatory=$True)][array]$MenuOptions
    )

    $MaxValue = $MenuOptions.count-1
    $Selection = 0
    $EnterPressed = $False
    
    Clear-Host

    While($EnterPressed -eq $False){

        For ($i=0; $i -le $MaxValue; $i++){
            
    $Width = if($Title){$Length = $Title.Length;$Length2 = $MenuOptions|%{$_.length}|Sort -Descending|Select -First 1;$Length2,$Length|Sort -Descending|Select -First 1}else{$MenuOptions|%{$_.length}|Sort -Descending|Select -First 1}
    $Buffer = if(($Width*1.5) -gt 78){(78-$width)/2}else{$width/4}
    if($Buffer -gt 6){$Buffer = 6}
    $MaxWidth = $Buffer*2+$Width+$($MenuOptions.count).length
    $Menu = @()
    $Menu += "╔"+"═"*$maxwidth+"╗"
    if($MenuTitle){
        $Menu += "║"+" "*[Math]::Floor(($maxwidth-$MenuTitle.Length)/2)+$MenuTitle+" "*[Math]::Ceiling(($maxwidth-$MenuTitle.Length)/2)+"║"
        $Menu += "╟"+"─"*$maxwidth+"╢"
    }
    For($i=1;$i -le $MenuOptions.count;$i++){
        $Item = "$i`. "
        $Menu += "║"+" "*$Buffer+$Item+$MenuOptions[$i-1]+" "*($MaxWidth-$Buffer-$Item.Length-$MenuOptions[$i-1].Length)+"║"
    }
    $Menu += "╚"+"═"*$maxwidth+"╝"
    $menu
}

        $KeyInput = $host.ui.rawui.readkey("NoEcho,IncludeKeyDown").virtualkeycode

        Switch($KeyInput){
            13{
                $EnterPressed = $True
                $script:Selection = "$Selection"
                Clear-Host
                break
            }

            38{
                If ($Selection -eq 0){
                    $Selection = $MaxValue
                } Else {
                    $Selection -= 1
                }
                Clear-Host
                break
            }

            40{
                If ($Selection -eq $MaxValue){
                    $Selection = 0
                } Else {
                    $Selection +=1
                }
                Clear-Host
                break
            }
            Default{
                Clear-Host
            }
        }
    }
}

#MainMenu
Function MainMenu (){
Create-Menu -MenuTitle "Tool" -MenuOptions "Lookup","Prep","Tools","Settings","Cleanup and Exit"
If($script:Selection -eq 0) {Lookup}
If($script:Selection -eq 1) {PrepMenu} 
If($script:Selection -eq 2) {ToolsMenu} 
If($script:Selection -eq 3) {SettingsMenu} 
If($script:Selection -eq 4) {CleanupAndExit} 
}

MainMenu

pause

代码输出如下:

╔═════════════════════════╗
║          Tool           ║
╟─────────────────────────╢
║    1. Lookup            ║
║    2. Prep              ║
║    3. Tools             ║
║    4. Settings          ║
║    5. Cleanup and Exit  ║
╚═════════════════════════╝

【问题讨论】:

  • 你应该为powershell添加一个标签,否则没人会发现这个。
  • 欣赏建议。第一次发帖..
  • 请看我编辑的代码。虽然第一个答案有效,但第二个答案会产生更流畅的工作菜单而不会闪烁。如果您发现我的回答解决了您的问题,请点击左侧的 图标,考虑accepting。这将帮助其他有类似问题的人更轻松地找到它。

标签: powershell colors menu items


【解决方案1】:

您可以添加颜色(我使用的是绿色,但这取决于您)对您的代码进行一些小的调整:

function Create-Menu {
    Param(
        [Parameter(Mandatory=$True)][String]$MenuTitle,
        [Parameter(Mandatory=$True)][array]$MenuOptions
    )

    # test if we're not running in the ISE
    if ($Host.Name -match 'ISE') {
        Throw "This menu must be run in PowerShell Console"
    }

    $MaxValue = $MenuOptions.Count-1
    $Selection = 0
    $EnterPressed = $False

    While(!$EnterPressed) {
        # draw the menu
        Clear-Host
        for ($i = 0; $i -le $MaxValue; $i++){
            [int]$Width = [math]::Max($MenuTitle.Length, ($MenuOptions | Measure-Object -Property Length -Maximum).Maximum)
            [int]$Buffer = if (($Width * 1.5) -gt 78) { (78 - $width) / 2 } else { $width / 4 }
            $Buffer = [math]::Min(6, $Buffer)
            $MaxWidth = $Buffer * 2 + $Width + $MenuOptions.Count.ToString().Length
            Write-Host ("╔" + "═" * $maxwidth + "╗")
            # write the title if present
            if (!([string]::IsNullOrWhiteSpace($MenuTitle))) {
                $leftSpace  = ' ' * [Math]::Floor(($maxwidth - $MenuTitle.Length)/2)
                $rightSpace = ' ' * [Math]::Ceiling(($maxwidth - $MenuTitle.Length)/2)
                Write-Host ("║" + $leftSpace + $MenuTitle + $rightSpace + "║")
                Write-Host ("╟" + "─" * $maxwidth + "╢")
            }
            # write the menu option lines
            for($i = 0; $i -lt $MenuOptions.Count; $i++){
                $Item = "$($i + 1). "
                $Option = $MenuOptions[$i]
                $leftSpace  = ' ' * $Buffer
                $rightSpace = ' ' * ($MaxWidth - $Buffer - $Item.Length - $Option.Length)
                $line = "║" + $leftSpace + $Item + $Option + $rightSpace + "║"
                if ($Selection -eq $i) {
                    Write-Host $line -ForegroundColor Green
                }
                else {
                    Write-Host $line
                }
            }
            Write-Host ("╚" + "═" * $maxwidth + "╝")
        }
        # wait for an accepted key press
        do {
            $KeyInput = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown').VirtualKeyCode
        } while (13, 38, 40 -notcontains $KeyInput)


        Switch($KeyInput){
            13{
                $EnterPressed = $True
                return $Selection
            }
            38 {
                $Selection--
                if ($Selection -lt 0){ $Selection = $MaxValue }
                break
            }
            40 { 
                $Selection++
                if ($Selection -gt $MaxValue) { $Selection = 0 }
                # or:    $Selection = ($Selection + 1) % ($MaxValue + 1)
                break
            }
        }
    }
}

#MainMenu
function MainMenu {
    $selected = Create-Menu -MenuTitle "Tools" -MenuOptions "Lookup","Prep","Tools","Settings","Cleanup and Exit"
    switch ($selected) {
        0 {"Lookup"}
        1 {"PrepMenu"}
        2 {"ToolsMenu"}
        3 {"SettingsMenu"}
        4 {"CleanupAndExit"}
    }
}

MainMenu

编辑

只是为了好玩,上面的代码在每次重绘菜单之前使用Clear-Host,这会产生一个可行但闪烁的菜单。
在同一个菜单下方,但这次它在没有先清除控制台窗口的情况下重绘,从而使菜单更加流畅。

function Create-Menu {
    Param(
        [Parameter(Mandatory=$false)][string]  $MenuTitle = $null,
        [Parameter(Mandatory=$true)] [string[]]$MenuOptions
    )

    # test if we're not running in the ISE
    if ($Host.Name -match 'ISE') {
        Throw "This menu must be run in PowerShell Console"
    }

    $MaxValue = $MenuOptions.Count-1
    $Selection = 0
    $EnterPressed = $False
    [console]::CursorVisible = $false  # prevents cursor flickering
    Clear-Host

    while(!$EnterPressed) {
        # draw the menu without Clear-Host to prevent flicker
        [console]::SetCursorPosition(0,0)
        for ($i = 0; $i -le $MaxValue; $i++){
            [int]$Width = [math]::Max($MenuTitle.Length, ($MenuOptions | Measure-Object -Property Length -Maximum).Maximum)
            [int]$Buffer = if (($Width * 1.5) -gt 78) { (78 - $width) / 2 } else { $width / 4 }
            $Buffer = [math]::Min(6, $Buffer)
            $MaxWidth = $Buffer * 2 + $Width + $MenuOptions.Count.ToString().Length
            Write-Host ("╔" + "═" * $maxwidth + "╗")
            # write the title if present
            if (!([string]::IsNullOrWhiteSpace($MenuTitle))) {
                $leftSpace  = ' ' * [Math]::Floor(($maxwidth - $MenuTitle.Length)/2)
                $rightSpace = ' ' * [Math]::Ceiling(($maxwidth - $MenuTitle.Length)/2)
                Write-Host ("║" + $leftSpace + $MenuTitle + $rightSpace + "║")
                Write-Host ("╟" + "─" * $maxwidth + "╢")
            }
            # write the menu option lines
            for($i = 0; $i -lt $MenuOptions.Count; $i++){
                $Item = "$($i + 1). "
                $Option = $MenuOptions[$i]
                $leftSpace  = ' ' * $Buffer
                $rightSpace = ' ' * ($MaxWidth - $Buffer - $Item.Length - $Option.Length)
                $line = "║" + $leftSpace + $Item + $Option + $rightSpace + "║"
                if ($Selection -eq $i) {
                    Write-Host $line -ForegroundColor Green
                }
                else {
                    Write-Host $line
                }
            }
            Write-Host ("╚" + "═" * $maxwidth + "╝")
        }
        # wait for an accepted key press
        do {
            $KeyInput = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown').VirtualKeyCode
        } while (13, 38, 40 -notcontains $KeyInput)


        Switch($KeyInput){
            13{
                $EnterPressed = $True
                [console]::CursorVisible = $true  # reset the cursors visibility
                return $Selection
            }
            38 {
                $Selection--
                if ($Selection -lt 0){ $Selection = $MaxValue }
                break
            }
            40 { 
                $Selection++
                if ($Selection -gt $MaxValue) { $Selection = 0 }
                # or:    $Selection = ($Selection + 1) % ($MaxValue + 1)
                break
            }
        }
    }
}

#MainMenu
function MainMenu {
    $selected = Create-Menu -MenuTitle "Tools" -MenuOptions "Lookup","Prep","Tools","Settings","Cleanup and Exit"
    switch ($selected) {
        0 {"Lookup"}
        1 {"PrepMenu"}
        2 {"ToolsMenu"}
        3 {"SettingsMenu"}
        4 {"CleanupAndExit"}
    }
}

MainMenu

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    • 2016-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多