Last active
December 6, 2021 21:11
-
-
Save DBremen/73d7999094e7ac342ad6 to your computer and use it in GitHub Desktop.
An alternative to the built-in PromptForChoice providing a consistent UI across different hosts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#An alternative to the built-in PromptForChoice providing a consistent UI across different hosts | |
function Get-Choice { | |
[CmdletBinding()] | |
Param | |
( | |
[Parameter(Mandatory=$true,Position=0)] | |
$Title, | |
[Parameter(Mandatory=$true,Position=1)] | |
[String[]] | |
$Options, | |
[Parameter(Position=2)] | |
$DefaultChoice = -1 | |
) | |
if ($DefaultChoice -ne -1 -and ($DefaultChoice -gt $Options.Count -or $DefaultChoice -lt 1)){ | |
Write-Warning "DefaultChoice needs to be a value between 1 and $($Options.Count) or -1 (for none)" | |
exit | |
} | |
Add-Type -AssemblyName System.Windows.Forms | |
Add-Type -AssemblyName System.Drawing | |
[System.Windows.Forms.Application]::EnableVisualStyles() | |
$script:result = "" | |
$form = New-Object System.Windows.Forms.Form | |
$form.FormBorderStyle = [Windows.Forms.FormBorderStyle]::FixedDialog | |
$form.BackColor = [Drawing.Color]::White | |
$form.TopMost = $True | |
$form.Text = $Title | |
$form.ControlBox = $False | |
$form.StartPosition = [Windows.Forms.FormStartPosition]::CenterScreen | |
#calculate width required based on longest option text and form title | |
$minFormWidth = 100 | |
$formHeight = 44 | |
$minButtonWidth = 70 | |
$buttonHeight = 23 | |
$buttonY = 12 | |
$spacing = 10 | |
$buttonWidth = [Windows.Forms.TextRenderer]::MeasureText((($Options | sort Length)[-1]),$form.Font).Width + 1 | |
$buttonWidth = [Math]::Max($minButtonWidth, $buttonWidth) | |
$formWidth = [Windows.Forms.TextRenderer]::MeasureText($Title,$form.Font).Width | |
$spaceWidth = ($options.Count+1) * $spacing | |
$formWidth = ($formWidth, $minFormWidth, ($buttonWidth * $Options.Count + $spaceWidth) | Measure-Object -Maximum).Maximum | |
$form.ClientSize = New-Object System.Drawing.Size($formWidth,$formHeight) | |
$index = 0 | |
#create the buttons dynamically based on the options | |
foreach ($option in $Options){ | |
Set-Variable "button$index" -Value (New-Object System.Windows.Forms.Button) | |
$temp = Get-Variable "button$index" -ValueOnly | |
$temp.Size = New-Object System.Drawing.Size($buttonWidth,$buttonHeight) | |
$temp.UseVisualStyleBackColor = $True | |
$temp.Text = $option | |
$buttonX = ($index + 1) * $spacing + $index * $buttonWidth | |
$temp.Add_Click({ | |
$script:result = $this.Text; $form.Close() | |
}) | |
$temp.Location = New-Object System.Drawing.Point($buttonX,$buttonY) | |
$form.Controls.Add($temp) | |
$index++ | |
} | |
$shownString = '$this.Activate();' | |
if ($DefaultChoice -ne -1){ | |
$shownString += '(Get-Variable "button$($DefaultChoice-1)" -ValueOnly).Focus()' | |
} | |
$shownSB = [ScriptBlock]::Create($shownString) | |
$form.Add_Shown($shownSB) | |
[void]$form.ShowDialog() | |
$result | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Is there any way to add a new line per button, essentially creating a "vertical list" of buttons?